我想枚举 Java 中有限正则表达式的所有可能值以进行测试。
对于某些上下文,我有一个正则表达式,用于匹配单词中允许的颜色值。这是它的简化版本作为示例:
(white|black)|((light|dark) )?(red|green|blue|gray)
我想创建一个单元测试,它会枚举所有这些值并将它们传递给我的实用程序类,该实用程序类会从中生成一个
Color
对象,这样如果我更改正则表达式,如果出现错误,我的单元测试将失败发生(即不支持新的颜色值)。
我当然知道枚举是可能的(参见这个问题),但是是否有一个现有的 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 将正则表达式转换为自动机,然后遍历自动机转换,在每个节点中进行随机选择。
主要功能是生成:
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 秒..
我还建议首先检查正则表达式是否确实是finate,方法是检查它是否包含 *、+ 和其他使此操作不可能的符号(只是为了使其成为一个可供重用的完整工具)...
对于未来遇到这个问题的浏览器,我编写了一个使用 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"
虽然这个问题已经很老了,但我最近开发了一个名为 regex-enumerator 的 Python 库,它可以枚举与有限正则表达式匹配的所有字符串。如果您愿意使用 Python 来完成您的任务,这个库可能会有用。它在 PyPI 上可用,因此您可以使用以下命令轻松安装它:
pip install regex-enumerator
以下是如何使用它的示例:
from regex_enumerator import RegexEnumerator
# Initialize the RegexEnumerator with your regex pattern
re = RegexEnumerator(r'a[0-9]b')
# Generate strings that match the pattern, one at a time
print(re.next()) # a0b
print(re.next()) # a1b
print(re.next()) # a2b
该库专为您需要系统地枚举正则表达式的所有可能匹配的情况而设计,使其适合诸如详尽测试或生成数据集之类的任务。
虽然最初的问题专门要求 Java 解决方案,但如果您愿意利用 Python,则该库可以作为替代方法。