我希望从包含数字的字符串生成正则表达式,然后将其用作模式来搜索类似的字符串。例如:
String s = "Page 3 of 23"
如果我用\d
StringBuilder sb = new StringBuilder();
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (Character.isDigit(c)) {
sb.append("\\d"); // backslash d
} else {
sb.append(c);
}
}
Pattern numberPattern = Pattern.compile(sb.toString());
// Pattern numberPattern = Pattern.compile("Page \d of \d\d");
我可以使用它来匹配类似的字符串(例如"Page 7 of 47"
)。我的问题是,如果我天真地这样做,一些元字符,如(){}-
等将不会被转义。是否有一个库可以执行此操作,或者是正则表达式的详尽字符集,我必须且不能逃避? (我可以尝试从Javadocs中提取它们,但我担心会遗漏一些东西。)
另外还有一个已经执行此操作的库(我现阶段不想使用完整的自然语言处理解决方案)。
注意:@ dasblinkenlight编辑的答案现在适合我!
答案 0 :(得分:10)
Java的regexp库提供了这个功能:
String s = Pattern.quote(orig);
“quoted”字符串将使其所有元字符都被转义。首先,转义字符串,然后遍历它并用\d
替换数字以生成正则表达式。由于正则表达式库使用\Q
和\E
进行引用,因此您需要将正则表达式的部分用\E
和\Q
的反引号括起来。
我在实现中会改变的一件事是替换算法:我会替换组中的数字,而不是逐字符替换。这样,Page 3 of 23
生成的表达式就会匹配Page 13 of 23
和Page 6 of 8
等字符串。
String p = Pattern.quote(orig).replaceAll("\\d+", "\\\\E\\\\d+\\\\Q");
无论最初有哪些页码和计数,这都是produce "\QPage \E\d+\Q of \E\d+\Q\E"
。输出只需要\d
中的一个而不是两个斜杠,因为结果直接送到regex引擎,绕过了Java编译器。