枚举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"