9

我想枚举 Java 中有限正则表达式的所有可能值以进行测试。

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

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

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

当然,我知道枚举是可能的(请参阅这个问题),但是是否有一个现有的 Java 库可以枚举正则表达式的所有可能匹配项?

编辑:我已经实现了一个这样做的库。请参阅下面的链接以获取我的答案。

4

2 回答 2

3

你是对的,在网上也没有找到这样的工具,但你可以试试谷歌的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 秒的时间来编写代码..

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

于 2012-12-05T13:08:12.670 回答
1

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

要将其添加为依赖项:

马文

<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"
于 2017-12-12T22:03:19.773 回答