这是一系列教育正则表达式文章的第三部分。它遵循How does this regex find triangular numbers?(首先引入嵌套引用)和How can we match a^n b^n with Java regex? (前瞻性“计数”机制进一步详述)。这部分介绍了一种特定形式的嵌套断言,当与嵌套引用结合使用时,Java正则表达式可以匹配大多数人认为“不可能”的东西:回文!!
回文的语言是非regular;它实际上是context-free(对于给定的字母表)。也就是说,现代正则表达式实现不仅仅识别常规语言,而且Perl / PCRE的递归模式和.NET的平衡组可以很容易地识别回文(参见:相关问题)。
然而,Java的正则表达式引擎既不支持这些“高级”功能。然而“某人”( * wink * )成功编写了以下正则表达式,这似乎很好地完成了工作(see also on ideone.com):
public class Palindrome {
// asserts that the entirety of the string matches the given pattern
static String assertEntirety(String pattern) {
return "(?<=(?=^pattern$).*)".replace("pattern", pattern);
}
public static void main(String[] args) {
final String PALINDROME =
"(?x) | (?:(.) add)+ chk"
.replace("add", assertEntirety(".*? (\\1 \\2?)"))
.replace("chk", assertEntirety("\\2"));
System.out.println(PALINDROME);
// (?x) | (?:(.) (?<=(?=^.*? (\1 \2?)$).*))+ (?<=(?=^\2$).*)
String[] tests = {
"", // true
"x", // true
"xx", // true
"xy", // false
"xyx", // true
"xxx", // true
"xxyx", // false
"racecar", // true
"step on no pets", // true
"aManaPlanaCanalPanaMa", // true
"this is impossible", // FALSE!!!
};
for (String test : tests) {
System.out.printf("[%s] %s%n", test, test.matches(PALINDROME));
}
}
}
所以这似乎有效,但是怎么样?
共同感觉警告!!!
这不是检测回文的最佳方法;最多只有
O(N^3)
。使用更通用的编程语言执行此检测既更高效又更直接。您不希望使用正则表达式来检测回文,原因与您不希望使用正则表达式查找素数相同。也就是说,您将研究非递归非平衡组正则表达式如何检测回文,原因与您研究正则表达式如何用于素性测试的原因相同:这很有趣,很有挑战性,很有教育意义。
答案 0 :(得分:18)