我想在Java中枚举有限正则表达式的所有可能值以用于测试目的。
对于某些上下文,我有一个正则表达式,我用它来匹配单词中允许的颜色值。这是一个缩短版本的例子:
(white|black)|((light|dark) )?(red|green|blue|gray)
我想创建一个单元测试,它将枚举所有这些值并将它们传递给我的实用程序类,该实用程序类从这些中生成Color
对象,这样如果我更改正则表达式,我的单元测试将会如果发生错误则失败(即不支持新的颜色值)。
我知道枚举是可能的,当然(see this question),但是现有的Java库是否会列举正则表达式的所有可能匹配项?
编辑:我已经实现了一个执行此操作的库。请参阅下面的答案以获取链接。
答案 0 :(得分: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秒。
我还建议首先检查正则表达式是否真的有效,通过检查它没有*,+和其他符号使得这个动作不可能(只是为了使它成为一个完整的重用工具)... < / p>
答案 1 :(得分:0)
对于未来的浏览器来说,我写了一个使用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"