Search for a palindrome using regex

This question comes to an attempt to understand one of the answers in: How to check that a string is a palindrome using regular expressions?

The answer to this question is Markus Jarderot:

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

Maybe someone will explain what is happening here ... I need to do something like this in Perl , but I am not able to understand this solution !!!

PS: I'm not very good at perl, so please go through ... and also β€œit cannot be considered a regular expression if you want to be strict” - I read this line, so I know that this is not a regular expression

+8
regex perl palindrome
source share
3 answers
  • ^ - matches the beginning of a line
  • ( - starts capture group # 1
  • (.) - matches any single character except a newline, saves it in capture group # 2
  • (?1) - recurse = replace this group with the entire capture group regexp # 1
  • \2 - matches the same as capture group # 2. This requires that the first and last characters of the string match each other
  • | - creates an alternative
  • .? - optionally matches any character that is not a newline character. This handles the end of the recursion by matching an empty string (when the whole string is uniform) or a single character (when it's an odd length)
  • ) - ends capture group # 1
  • $ - matches the end of a line or before a new line at the end of a line.

Recursion (?1) is the key. A palindrome is an empty string, a 1-character string or a string whose first and last characters are the same, and the substring between them is also a palindrome.

+13
source share

This might be easier to understand with this similar function, which does the same for arrays:

 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)); 

The notation (?1) is a recursive reference to the beginning of the first bracket in the regular expression, \2 is the back reference in the current recursion to (.) . These two are tied to the beginning and end of "everything that matches the current recursion depth", so everything else is matched down to the next depth.


ikegami suspects this is faster:

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

I did this regEx a few days ago. If you use it like this, it will give you an array of all the palindromes in the specific text. An example is for #JavaScript, but you can use regEx itself in any language to complete the task. Works perfect for words up to 21 characters or numbers up to 21 digits. You can make it more accurate if you need to.


 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)); 
0
source share

All Articles