Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW
 
PerlMonks  

Can "delayed-regex assertions" be nested...

by ddn123456 (Pilgrim)
on Feb 21, 2008 at 10:43 UTC ( [id://669233]=perlquestion: print w/replies, xml ) Need Help??

ddn123456 has asked for the wisdom of the Perl Monks concerning the following question:

Dear Monks,

I'm stuck on "delayed-regex assertions" here.

Can "delayed-regex assertions" be nested with perl v5.8.6 built for MSWin32-x86-multi-thread on win xp SP2 32bit?

When I tried this I get:
Sequence (?{...}) not terminated or not {}-balanced in regex; marked by <-- HERE in m/(??{ <-- HERE join( '|', grep ( /

I gave anonymous sub routines a shot but didn't get far there.

Code example:

<code> use Data::Dumper;
my @A = ( "ab", "abcd", "f" );
my %H = (
'ab' => 0,
'abcd' => 1,
#'def' => 2,
);

# 1st working alternative
foreach $i (@A){if (!(grep (/$i/i, keys %H))){print "$i\n";};};


# 2nd working alternative
@B = grep ( /(??{join( '|', @A)})/gi, keys %H );
@B = grep ( !/(??{join( '|', @B)})/gi, @A );

# Imagined Code with the issue
# @B = grep ( !/(??{join( '|', grep ( /(??{join( '|', @A)})/gi, keys %H ) })/gi, @A );

# Issue Code Perl -c output
# Sequence (?{...}) not terminated or not {}-balanced in regex; marked by <-- HERE in m/(??{ <-- HERE join( '|', grep ( /
print "Delta:\n";
print Dumper(@B);


##Output
##Delta:
##$VAR1 = 'f';
< /code>


Many, many thanks in advance.

ddn123456
  • Comment on Can "delayed-regex assertions" be nested...

Replies are listed 'Best First'.
Re: Can "delayed-regex assertions" be nested...
by moritz (Cardinal) on Feb 21, 2008 at 10:56 UTC
    I assume that you have read perlre, and the warning there that (??{ ... }) is highly experimental. It's not there without a reason.

    I noticed that even a simple regex in a (??{...}) block doesn't work:

    #!/usr/bin/perl use strict; use warnings; $_ = "foo"; print "a" =~ m{.} ? "o\n" : "O\n"; if ( m/f (??{ "a" =~ m{.} ? 'o' : 'O' }) o/x){ print "matched\n" } __END__ o

    In your position I'd precompute the regex instead of trying to stuff it all in one line.

      Hi Moritz,

      Thx for the feedback.

      Yes I've read the perlre. Unfortunately my client interpretes highly experimental by default as "Oh. So it's feasible". :-)

      Precomputing the most inner block gives the same result.

      With kind regards.

      DirkDn
        Unfortunately my client interpretes highly experimental by default as "Oh. So it's feasible". :-)

        As a programmer it's your job to tell him otherwise.

        If possible create an example that segfaults (for example try some fun with closures inside the block), and show that to your client ;-)

        Precomputing the most inner block gives the same result.

        Then you have to unroll one more level:

        !/usr/bin/perl use strict; use warnings; use Data::Dumper; my @A = ( "ab", "abcd", "f" ); my %H = ( 'ab' => 0, 'abcd' => 1, #'def' => 2, ); my $re_inner = join( '|', @A); my $re_outer = join '|', grep /$re_inner/gi, keys %H; my @B = grep ( !/$re_outer/gi, @A ); print Dumper(\@B);

        Disclaimer: I haven't actually understood what you try to achieve, maybe there's a better solution altogether.

Re: Can "delayed-regex assertions" be nested...
by hipowls (Curate) on Feb 21, 2008 at 19:23 UTC

    From perlre for 5.10.0

    Because Perl's regex engine is currently not re-entrant, interpolated code may not invoke the regex engine either directly with m// or s///), or indirectly with functions such as split.
    I'm sure that it's the same for 5.8. It seems unlikely that p5p would remove such a desirable feature;)

      Dear Monks Moritz, Ikegami & Hipowls,

      A bit delayed reply since I was offline due to a flue.

      Thanks a lot for this precious information. I've learned a lot from it.

      With kind regards.
      ddn123456
Re: Can "delayed-regex assertions" be nested... (min fix)
by ikegami (Patriarch) on Feb 21, 2008 at 18:53 UTC

    The syntax error you are getting is due to the presence of the regexp delimiter in the (??{...}) assertion. To make your original code with minimum change, change
    @B = grep ( !/(??{join( '|', grep ( /(??{join( '|', @A)})/gi, keys %H ) })/gi, @A );
    to
    @B = grep ( !/(??{join( '|', grep ( m!(??{join( '|', @A)})!gi, keys %H ) })/gi, @A );

    Update: hipowls notes that even if you fix the syntax error (as shown in this post), it won't work because the regexp engine is not re-entrant.

Re: Can "delayed-regex assertions" be nested...(text2re bug)
by ikegami (Patriarch) on Feb 21, 2008 at 18:47 UTC
    If @A contains text, not regexs, then join( '|', @A ) should be join( '|', map quotemeta, @A ). Same for @B.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://669233]
Approved by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others imbibing at the Monastery: (6)
As of 2024-04-23 15:42 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found