这个Java正则表达式如何检测回文?

时间:2010-09-08 05:34:21

标签: java regex palindrome lookaround nested-reference

  

这是一系列教育正则表达式文章的第三部分。它遵循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)。使用更通用的编程语言执行此检测既更高效又更直接。

     

您不希望使用正则表达式来检测回文,原因与您不希望使用正则表达式查找素数相同。也就是说,您将研究非递归非平衡组正则表达式如何检测回文,原因与您研究正则表达式如何用于素性测试的原因相同:这很有趣,很有挑战性,很有教育意义。

相关问题

1 个答案:

答案 0 :(得分:18)

相关问题