Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

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

0 views
Skip to first unread message

Hartmut Camphausen

unread,
Jul 26, 2008, 2:42:26 PM7/26/08
to

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

--
------------------------------------------------
Hartmut Camphausen h.camp[bei]textix[punkt]de

comp.lang.c++

unread,
Jul 29, 2008, 6:32:09 PM7/29/08
to
On Jul 26, 11:42 am, Hartmut Camphausen <Jus...@somewhere.de> wrote:
> 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>

--
Ch<arles DeRykus

comp.lang.c++

unread,
Jul 29, 2008, 7:26:24 PM7/29/08
to
On Jul 29, 3:32 pm, "comp.lang.c++" <c...@blv-sam-01.ca.boeing.com>
wrote:

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

> --
> Ch<arles DeRykus

Dr.Ruud

unread,
Jul 31, 2008, 5:27:24 PM7/31/08
to
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.

--
Affijn, Ruud

"Gewoon is een tijger."

Hartmut Camphausen

unread,
Aug 2, 2008, 7:28:16 AM8/2/08
to
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,

0 new messages