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
Re: Can "delayed-regex assertions" be nested...
by moritz (Cardinal) on Feb 21, 2008 at 10:56 UTC
|
#!/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. | [reply] [d/l] [select] |
|
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
| [reply] |
|
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. | [reply] [d/l] |
|
|
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;)
| [reply] |
|
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
| [reply] |
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.
| [reply] [d/l] [select] |
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.
| [reply] [d/l] [select] |
|
|