【问题标题】:Enumerate Possible Matches of Regular Expression in Java枚举Java中正则表达式的可能匹配项
【发布时间】:2012-11-21 05:52:56
【问题描述】:

出于测试目的,我想枚举 Java 中有限正则表达式的所有可能值。

在某些情况下,我有一个正则表达式,用于匹配单词中允许的颜色值。以下是它的一个简化版本作为示例:

(white|black)|((light|dark) )?(red|green|blue|gray)

我想创建一个单元测试来枚举所有这些值并将它们中的每一个传递给我的实用程序类,该类会从这些生成一个Color 对象,这样如果我更改正则表达式,我的单元测试将失败,如果发生错误(即不支持新的颜色值)。

当然,我知道枚举是可能的 (see this question),但是是否有一个现有的 Java 库可以枚举正则表达式的所有可能匹配项?

编辑:我已经实现了一个库来执行此操作。请参阅下面的链接以获取我的答案。

【问题讨论】:

  • 您想要所有无限数量的可能匹配项(带有不同数量的空格),还是只需要有限数量的匹配项?
  • 你说finite regular expression,我想你的意思是regular expression that describes a finite language。请注意,在这种情况下,您的正则表达式不是“有限的”。它包含一个+
  • @m.buettner 啊,确实如此。我想我将不得不删除加号。哦,好吧,反正我不喜欢它。
  • 重新打开这个问题。链接的副本用于随机匹配生成,而不是所有可能匹配的生成。
  • 你需要这样的东西:regldg.com/docs/index.php 但我还没有看到 java impl

标签: java regex enumeration


【解决方案1】:

你是对的,在网上也没有找到这样的工具 但你可以试试谷歌的Xeger

它可以从一个正则表达式创建一个随机匹配的字符串,并且通过一些代码调整可能会做你想要的。 生成随机匹配:

String regex = "[ab]{4,6}c";
Xeger generator = new Xeger(regex);
String result = generator.generate();
assert result.matches(regex);

Xeger 代码非常简单,它由 2 个文件组成,它们之间包含 5 个方法..
它使用 dk.brics.automaton 将正则表达式转换为自动机,然后遍历自动机转换,在每个节点中进行随机选择。

主要功能是生成:

   private void generate(StringBuilder builder, State state) {
    List<Transition> transitions = state.getSortedTransitions(true);
    if (transitions.size() == 0) {
        assert state.isAccept();
        return;
    }
    int nroptions = state.isAccept() ? transitions.size() : transitions.size() - 1;
    int option = XegerUtils.getRandomInt(0, nroptions, random);
    if (state.isAccept() && option == 0) {          // 0 is considered stop
        return;
    }
    // Moving on to next transition
    Transition transition = transitions.get(option - (state.isAccept() ? 1 : 0));
    appendChoice(builder, transition);
    generate(builder, transition.getDest());
}

您可以看到,为了更改它以便获得所有可能的匹配项,您需要遍历每个可能节点中的所有可能组合(例如递增多位计数器) 您将需要一个哈希来防止循环,但这不应该超过 5 秒的代码..

我还建议首先检查正则表达式实际上是否已完成,通过检查它是否没有 *、+ 和其他使此操作不可能的符号(只是为了使其成为一个完整的重用工具)...

【讨论】:

  • +1,这几乎是我所期望的。我一直在研究dk.brics.automaton 及其在 Xeger 中的用法。幸运的是,dk.brics.automaton 是 BSD 许可的。也许我可以为此编写一个开源库,因为似乎没有其他人实现过这个(至少不是开源的)。
  • 根据您的有限评论,我应该只使用未封闭的量词,包括贪婪、不情愿和占有欲*+{n,}。我很确定只有这些会导致无限重复。
【解决方案2】:

对于将来遇到此问题的浏览器,我编写了一个库,该库使用dk.brics.automaton 使用与接受的答案中的Xeger 类似的方法并将其发布。你可以找到它:

将其添加为依赖项:

Maven

<dependency>
    <groupId>com.navigamez</groupId>
    <artifactId>greex</artifactId>
    <version>1.0</version>
</dependency>

分级

compile 'com.navigamez:greex:1.0'

示例代码

以这个问题为例:

GreexGenerator generator = new GreexGenerator("(white|black)|((light|dark) )?(red|green|blue|gray)");
List<String> matches = generator.generateAll();
System.out.println(matches.size()); // "14"

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-30
    • 2011-05-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多