此问题旨在了解其中一个答案: How to check that a string is a palindrome using regular expressions?
Markus Jarderot 给出的答案是:
/^((.)(?1)\2|.?)$/
有人可以解释一下,到底发生了什么......我需要在Perl
中做类似的事情,但是不能理解这个解决方案!!!
答案 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));