How come? RE matches, but does not set $^R

H

Hartmut Camphausen

Hi all,

Assume the following REs:

# this should match B, followed by e.g. '=cc', and set $^R to 'got B':
/(B(?:=c*))(?{'got B'})/

# so should this, but match '=c*' only once, if any, and set $^R:
/(B(?:=c*)?)(?{'got B'})/

Both expressions match as expected (and set $1), BUT: the second one
does n o t set $^R as it should do.

However, if I say

/(?>(B(?:=c+)?)(?{...})/

i.e. force Perl to eat up anything it matches, $^R is correctly set.

How come?


Quite clueless, Hartmut
 
C

comp.lang.c++

Hi all,

Assume the following REs:

# this should match B, followed by e.g. '=cc', and set $^R to 'got B':
/(B(?:=c*))(?{'got B'})/

# so should this, but match '=c*' only once, if any, and set $^R:
/(B(?:=c*)?)(?{'got B'})/

Both expressions match as expected (and set $1), BUT: the second one
does n o t set $^R as it should do.

However, if I say

/(?>(B(?:=c+)?)(?{...})/

i.e. force Perl to eat up anything it matches, $^R is correctly set.

How come?

I believe $^R only contains the last successful
match so, as a minimal example:

print "\$^R=$^R" if "xx" =~ /(x)x?/'
$^R=

<speculation>
The regex matches greedily and picks up the
second 'x' but then backtracks to try the
"0 times match" of the ? quantifier. That
doesn't match so $^R is undefined at that
point. Therefore $^R is tracking success/
failure internally which can be somewhat
counter-inintuitive since $1 still gets
set.
</speculation>
 
C

comp.lang.c++

I believe $^R only contains the last successful
match so, as a minimal example:

print "\$^R=$^R" if "xx" =~ /(x)x?/'
$^R=

<speculation>
The regex matches greedily and picks up the
second 'x' but then backtracks to try the
"0 times match" of the ? quantifier. That
doesn't match so $^R is undefined at that
point. Therefore $^R is tracking success/
failure internally which can be somewhat
counter-inintuitive since $1 still gets
set.
</speculation>

Probably not. Since the ? quantifier is
greedy and picks up the next "x" there should
be no backtracking at all.

So, the $^R result does look flaky.

--
Charles DeRykus


 
D

Dr.Ruud

Hartmut Camphausen schreef:
Assume the following REs:

# this should match B, followed by e.g. '=cc', and set $^R to 'got
B': /(B(?:=c*))(?{'got B'})/

# so should this, but match '=c*' only once, if any, and set $^R:
/(B(?:=c*)?)(?{'got B'})/

Both expressions match as expected (and set $1), BUT: the second one
does n o t set $^R as it should do.

However, if I say

/(?>(B(?:=c+)?)(?{...})/

i.e. force Perl to eat up anything it matches, $^R is correctly set.

How come?

Most probably a bug: if there is a quantifier at the end of the
non-capturing group, and a quantifier directly after that group, then
$^R is undefined.
 
H

Hartmut Camphausen

Am Thu, 31 Jul 2008 23:27:24 +0200 schrieb Dr.Ruud:

Thanks Charles & Ruud for investigating my little problem.
Dr.Ruud wrote:
Most probably a bug: if there is a quantifier at the end of the
non-capturing group, and a quantifier directly after that group, then
$^R is undefined.

This also happens for capturing groups.

As I just found out:
This seems to apply only if I do not set $^R explicitly via (?{$^R=...})
If I do so, everything works as expected.

So under these conditions Perl does not return the result of the last
statement within the code block as it otherwise uses to. (Well, as the
docs say, "This extended regular expression feature is considered highly
experimental"...)


So, I see two workarounds for this maybe rare case:

(1) set $^R explicitly:

(a+)?(?{$^R=...})

(2) enclose the search expression in (?>...):

(?>(a+)?)(?{...})



Thanks again + mfg,
Hartmut
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,576
Members
45,054
Latest member
LucyCarper

Latest Threads

Top