Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?

Iterating over code embeded in regex

by eibwen (Friar)
on Jun 13, 2006 at 03:30 UTC ( #554941=perlquestion: print w/replies, xml ) Need Help??
eibwen has asked for the wisdom of the Perl Monks concerning the following question:

I'd like to run a few lines of code on each instance of a string of a particular form. To accomplish this I've been using a regex of the form:

$s =~ /(string)(?{ print $^N, $/; })(?!)/;

While this works to print all occurances of the string in question (see Global Regex sans //g), I cannot seem to get this to work in list (or perhaps array) context:

my @letters = ('a'..'z'); for my $letter (0..$#letters) { $letters[$letter] =~ /(?{ print $letter })(?!)/; }

The code seems to run each iteration; however instead of printing the current value of $letter, it returns the following error:

Use of uninitialized value in print at (re_eval 1) line 1.

As I type this I wonder if the regex and the embeded code are being compiled prior to the instantion of the variable? I tried running it through Deparse, but it appeared to be more or less unaltered. Should this be the case, I'd surmise it happens afterwards -- perhaps at runtime?

How can I print the current value of the iteration from within the regex -- preferrably sans eval?

Replies are listed 'Best First'.
Re: Iterating over code embeded in regex
by ikegami (Pope) on Jun 13, 2006 at 03:47 UTC

    Don't use lexicals in code embedded in regexp. Use package variables.

    my @letters = ('a'..'z'); for our $letter (0..$#letters) { $letters[$letter] =~ /(?{ print $letter })(?!)/; }
Re: Iterating over code embeded in regex
by Samy_rio (Vicar) on Jun 13, 2006 at 04:01 UTC

    Hi eibwen, Try like this,

    use strict; use warnings; my @letters = ('a'..'z'); for (0..$#letters) { $letters[$_] =~ m/(?{ print $_ })(?!)/; }

    Velusamy R.

    eval"print uc\"\\c$_\""for split'','j)@,/6%@0%2,`e@3!-9v2)/@|6%,53!-9@2~j';

Re: Iterating over code embeded in regex
by ioannis (Monsignor) on Jun 13, 2006 at 05:34 UTC
    The snippet bellow shows that the $l inside the embedded code of the regex is a closure.

    use Scalar::Util 'refaddr'; for my $l ('a'..'b') { print 'loop variable ', refaddr \$l; $l =~ /(?{ print refaddr(\$l) }) /x; }

    Here is the output:

    loop variable 135603848 135606104 loop variable 135606092 135606104
Re: Iterating over code embeded in regex
by ambrus (Abbot) on Jun 13, 2006 at 12:31 UTC

    I think you shouldn't use the (?{...}) construct without a very good reason. To run some code on all matches of a regexp in a string, you can do this for example (untested):

    while ($string =~ /(pattern)/g) { do_something_with($1); }
    Or, if you want overlapping matches too, then
    while ($string =~ /(?=(patter))/g) { do_something_with($1); }

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://554941]
Approved by Samy_rio
and a soft breeze sighs...

How do I use this? | Other CB clients
Other Users?
Others avoiding work at the Monastery: (5)
As of 2018-03-19 01:59 GMT
Find Nodes?
    Voting Booth?
    When I think of a mole I think of:

    Results (231 votes). Check out past polls.