使用正则表达式查找回文

时间:2014-03-12 10:59:01

标签: regex perl palindrome

此问题旨在了解其中一个答案: How to check that a string is a palindrome using regular expressions?

Markus Jarderot 给出的答案是:

/^((.)(?1)\2|.?)$/

有人可以解释一下,到底发生了什么......我需要在Perl中做类似的事情,但是不能理解这个解决方案!!!

PS:我在perl方面不是很好,所以请放轻松......而且"如果你想严格要求,这不能算是正则表达式。 - 我读了这一行,所以我知道这不是正则表达式严格

3 个答案:

答案 0 :(得分:13)

  • ^ - 匹配字符串的开头
  • ( - 开始捕获组#1
  • (.) - 匹配除换行符之外的任何单个字符,将其保存在捕获组#2
  • (?1) - recurse =将此组替换为整个regexp捕获组#1
  • \2 - 与捕获组#2匹配相同的内容。这要求字符串的第一个和最后一个字符相互匹配
  • | - 创建替代
  • .? - 可选地匹配任何不是换行符的字符 - 这通过匹配空字符串(当整个字符串是偶数长度)或单个字符(当时)来处理递归的结束这是一个奇怪的长度)
  • ) - 结束捕获组#1
  • $ - 匹配字符串的结尾或字符串末尾的换行符之前。

递归(?1)是关键。回文是空字符串,1个字符的字符串,或者第一个和最后一个字符相同的字符串,它们之间的子字符串也是回文。

答案 1 :(得分:3)

使用这个类似的函数可能更容易理解,它对数组做同样的事情:

sub palindrome {
  if (scalar(@_) >= 2) {
    my $first_dot = shift;
    my $slash_two = pop;
    return $first_dot eq $slash_two && palindrome(@_);
  } else {
    # zero or one items
    return 1;
  }
}

print "yes!\n" if palindrome(qw(one two three two one));
print "really?\n" if palindrome(qw(one two three two two one));

(?1)表示法是对正则表达式中第一个括号的开头的递归引用,\2是当前递归(.)的反向引用。这两个锚定在“当前递归深度”匹配的开头和结尾处,所以其他所有内容都在下一个深度处匹配。


ikegami怀疑这更快:

sub palindrome {
   my $next = 0;
   my %symbols;
   my $s = join '', map chr( $symbols{$_} ||= $next++ ), @_;
   return $s =~ /^((.)(?1)\2|.?)\z/s;
}

答案 2 :(得分:0)

几天前我做了这个regEx。 如果您以此方式使用它,它将在特定文本中为您提供所有回文的数组。 该示例适用于#JavaScript,但您可以使用任何语言的regEx本身来完成这项工作。 适用于21个字符或21个数字的数字。如果需要,可以使其更准确。


const palindromeFinder = /\b(\w?)(\w?)(\w?)(\w?)(\w?)(\w?)(\w?)(\w?)(\w?)(\w)\S?\10\9\8\7\6\5\4\3\2\1\b/g;

console.log(inputString.match(palindromeFinder));
相关问题