3

Consider the following Perl-flavoured?? (i suppose not?) regex to test if a string is a palindrome:

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

try it here.

the following

my regex palindrome {
    ^((.)(?1)\2|.?)$
}

say "$word is a palindrome"
    if $word ~~ /<palindrome>/
    && $word.chars > 1;

gives an error

===SORRY!===
Quantifier quantifies nothing
at /home/cat/projects/perl6/code/misc/words.pl6:6
------>   ^((.)(?⏏1)\2|.?)$
Unrecognized backslash sequence (did you mean $1?)
at /home/cat/projects/perl6/code/misc/words.pl6:6
------>   ^((.)(?1)\2⏏|.?)$

I have a working knowledge of (Python) regexes, and I get what it means when it says "Quantifier quantifies nothing", but I don't get why it says this when I was asking for recursion, not a quantification.

I don't have enough knowledge of Perl to know why it doesn't like the backslash (the other error).

I did try messing around with the syntax and searching around, but as far as I and the internet are concerned, this regex works, and fiddling with it generates various other errors I don't get.

What am I doing wrong?

Community
  • 1
  • 1
cat
  • 3,888
  • 5
  • 32
  • 61
  • 5
    There's currently [a discussion on Meta](http://meta.stackoverflow.com/q/315419/176646) about whether the `perl` tag can also be added to Perl 6 questions, but please *always* include the `perl6` tag. Otherwise you'll confuse all the Perl 5 developers who will wonder why your code looks so funny. – ThisSuitIsBlackNot Jan 26 '16 at 21:49
  • @ThisSuitIsBlackNot ahh, okay. – cat Jan 26 '16 at 21:49
  • You need to double the pipe: `^((.)(?1)\2||.?)$` – Wiktor Stribiżew Jan 26 '16 at 21:56
  • @WiktorStribiżew same error, no change. – cat Jan 26 '16 at 21:58
  • 3
    `(?1)` isn't a valid construct in Perl 6. Perl 6 regex isn't even remotely PCRE. – hobbs Jan 26 '16 at 22:11
  • 1
    `(?1)` is a [recursive subpattern](http://perldoc.perl.org/perlre.html#%28%3f_PARNO_%29-%28%3f-_PARNO_%29-%28%3f%2b_PARNO_%29-%28%3fR%29-%28%3f0%29) in Perl 5 regex, not a named capturing group. I'm not sure how to translate that into a Perl 6 regex (or if it can be done with a regex), but here are the [Perl 6 regex docs](https://doc.perl6.org/language/regexes). Be aware that the vast majority of Perl questions on SO ask about Perl 5, and trying to run Perl 5 code with Perl 6 will probably not work most of the time. – ThisSuitIsBlackNot Jan 26 '16 at 22:28
  • 2
    According to [this page](https://design.perl6.org/S05.html), it's `<~~>` to match the whole regex recursively, or you can specify a numbered ( `<~~0>`) or named ( `<~~foo>`) subpattern. – Alan Moore Jan 26 '16 at 22:47
  • Well, backreferences like `\1` are also [gone](https://design.perl6.org/S05.html#Backslash_reform). Well, try `^((.)<~~1>$2||.?)$`. Or `^<(<(.)><~~1>$2||.?)>$` (*You may also capture a subset of the match using the `<(...)>` construct*) – Wiktor Stribiżew Jan 26 '16 at 22:55
  • 2
    @WiktorStribiżew: capture group indices are 0-based, and `~~` assertions for capture groups are not implemented... – Christoph Jan 26 '16 at 23:01

1 Answers1

6

One way to do it is this:

my regex palindrome { (.) <~~> $0 || .? }
say "aba" ~~ /^<palindrome>$/;
Christoph
  • 164,997
  • 36
  • 182
  • 240
  • this considers every word a palindrome. – cat Jan 26 '16 at 23:19
  • 1
    @cat: not for me; what's your Rakudo version? – Christoph Jan 26 '16 at 23:41
  • `This is Rakudo version 2015.12-219-gd67cb03 built on MoarVM version 2015.12-29-g8079ca5 implementing Perl 6.c.` Full disclosure: I ran it on `/usr/share/dict/words` and piped its output to a file, then `diff`ed the files and there were no differences. – cat Jan 26 '16 at 23:44
  • I'm still on 2015.12-113, so I'll update and see what happens; could it be the problem lies elsewhere in your code? – Christoph Jan 26 '16 at 23:50
  • This definitely matches every string, and it's not just my code because the same goes for `perl6 -e` and the REPL. – cat Jan 26 '16 at 23:56
  • 1
    `$ perl6 -e 'my regex palindrome { (.) <~~> $0 || .? }; say "ab" ~~ /^$/' # Nil` – Christoph Jan 26 '16 at 23:57
  • 3
    Oh! I had missed the `^` and `$` in the application of the regex. My mistake, you're right. – cat Jan 27 '16 at 00:07