http://www.perlmonks.org?node_id=968179

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

Dear Monks

I have a long text stored in a variable $text (the problem is, the text must remain in this simple variable). I search with a Regexp in this variable through a while loop

while ( $text =~ /$query/gi ) { do_something(); }

What I'd like to do is to add another condition: **if $text =~ /$query_modified/gi {do_something_different();}**

Why: the sub do_something must process some information depending on the presence of $query_modified in the variable $text. As these conditions may vary across $text, I need to run the two conditions in a way different as the next one proposed which is not good for me as I need to process the two conditions at the same time.

while ( $text =~ /$query/gi ) { do_something(); } while ( $text =~ /$query_modified/gi ) { do_something_different(); }

Is there a way to perform this?

Replies are listed 'Best First'.
Re: While two conditions
by BrowserUk (Patriarch) on May 01, 2012 at 02:21 UTC

    Do you mean something like this?

    if( $text =~ /$query/i ) { while ( $text =~ /$query/gi ) { do_something(); } } elsif( $text =~ /$query_modified/i ) { while ( $text =~ /$query_modified/gi ) { do_something_different(); } } else { ## Is this possible? }

    Or perhaps:

    while ( $text =~ /($query|$query_modified)/gi ) { if( $1 eq $query ) { do_something(); } else { do_something_else(); } }

    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.

    The start of some sanity?

      A good answer to what he asked .. but not what he wanted. XY problem, I think.
Re: While two conditions
by GrandFather (Saint) on May 01, 2012 at 00:47 UTC

    It is hard to imagine what you are trying to achieve without a concrete example. Maybe generating an array of matches from your master string using your first match criteria, then filtering the array using your second match may do what you need. Otherwise I at least need to see a real sample string (keep it short please) and two example match criteria to be much more help.

    True laziness is hard work

      I am adapting Lingua::Concordance. It takes all occurences of $query and show it with its context in a ordered way.

      Here is the code

      $text="Oldfield's career began fairly early, playing <1> acoustic guit +ar in local folk clubs. At this time, he already had two fifteen-minu +te instrumental pieces in which he would "go through all <2>sorts of +moods", precursors to his landmark 1970s' compositions. In his early +teens, Oldfield was involved in a 'beat group' <3>playing Shadows-sty +le music (he has often cited Hank Marvin as a major influence, and wo +uld later cover The Shadows' song "Wonderful Land")." $query="in"; while ( $text =~ /$query/gi ) { my $match = $1; my $pos = pos( $text ); my $start = $pos - $self->radius - length( $match ); my $extract = ''; if ( $start < 0 ) { $extract = substr( $text, 0, $width + $start + length( $ma +tch )); $extract = ( " " x -$start ) . $extract; } else { $extract = substr( $text, $start, $width + length( $match +)); my $deficit = $width + length( $match ) - length( $extract + ); if ( $deficit > 0 ) { $extract .= ( " " x $deficit ) } } push @lines, $extract; }

      What I am trying to do is to read the <> tag and associate it to the corresponding $extract (for example: "guitar in local folk" seen after <1>)

        It's hard to tell exactly what you want to do, but a first guess is that my original suggestion was exactly on the money. Consider:

        use strict; use warnings; use Lingua::Concordance; my $text = <<TEXT; Oldfield's career began fairly early, playing <1> acoustic guitar in l +ocal folk clubs. At this time, he already had two fifteen-minute instrumental pi +eces in which he would "go through all <2>sorts of moods", precursors to his l +andmark 1970s' compositions. In his early teens, Oldfield was involved in a 'b +eat group' <3>playing Shadows-style music (he has often cited Hank Marvin as a ma +jor influence, and would later cover The Shadows' song "Wonderful Land"). TEXT my $query = 'in'; my $concordance = Lingua::Concordance->new (); $concordance->radius(25); $concordance->text($text); $concordance->query($query); my @matches = $concordance->lines(); my @pairs; for my $match (@matches) { while ($match =~ /<(\d+)>.*?$query/g) { push @pairs, map {[$_, $match]} $1 if $-[0] < $concordance->r +adius(); } } print "$_->[0]: $_->[1]\n" for @pairs;

        Prints:

        1: ng <1> acoustic guitar in local folk clubs. At thi 3: a 'beat group' <3>playing Shadows-style music (he
        True laziness is hard work
Re: While two conditions
by Anonymous Monk on May 01, 2012 at 09:22 UTC
    my $text = 'perl monks'; my $query = qr{ (?<M>monk) (?(<M>)(?{do_something_different()})) | (?<P>perl) (?(<P>)(?{do_something()})) }x; while($text =~ /$query/gi){}; sub do_something{ print "found perl\n"; } sub do_something_different{ print "found monk\n"; }

      It looks like it could be something for me, BUT - excuse my ignorance - waht kind of sintax is this:

      my $query = qr{ (?<M>monk) (?(<M>)(?{do_something_different()})) | (?<P>perl) (?(<P>)(?{do_something()})) }x;

      With perl 5.8.9 it just doesn't work