枚举Java中正则表达式的可能匹配项
我想在Java中枚举有限正则表达式的所有可能值以用于测试目的。
对于某些上下文,我有一个正则表达式,我用它来匹配单词中允许的颜色值。 这是一个缩短版本的例子:
(white|black)|((light|dark) )?(red|green|blue|gray)
我想创建一个unit testing,它将枚举所有这些值并将它们传递给我的实用程序类,该实用程序类从这些中生成一个Color
对象,这样,如果我更改正则表达式,我的unit testing将在发生错误时失败(即新颜色值不受支持)。
当然,我知道枚举是可能的( 参见这个问题 ),但是现有的Java库是否会枚举正则表达式的所有可能的匹配?
编辑:我已经实现了一个执行此操作的库。 请参阅下面的答案以获取链接。
你是对的,也没有在网上找到这样的工具,但你可以从谷歌尝试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将正则表达式转换为自动机,然后遍历自动机转换,在每个节点中进行随机选择。
主要function是生成:
private void generate(StringBuilder builder, State state) { List 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秒
我还建议首先检查正则表达式是否真的有效,通过检查它没有*,+和其他符号使这个动作不可能(只是为了使这个工具成为一个完整的工具)…
对于未来的浏览器来说,我写了一个使用dk.brics.automaton的库,使用与接受的答案类似的Xeger方法并发布它。 你可以找到它:
- 在GitHub上
- 在项目现场
- 在Maven Central
要将其添加为依赖项:
Maven的
com.navigamez greex 1.0
摇篮
compile 'com.navigamez:greex:1.0'
示例代码
以此问题为例:
GreexGenerator generator = new GreexGenerator("(white|black)|((light|dark) )?(red|green|blue|gray)"); List matches = generator.generateAll(); System.out.println(matches.size()); // "14"