Beefy Boxes and Bandwidth Generously Provided by pair Networks vroom
There's more than one way to do things
 
PerlMonks  

Determing if this regex matched

by cormanaz (Chaplain)
on Aug 06, 2011 at 19:29 UTC ( #918978=perlquestion: print w/ replies, xml ) Need Help??
cormanaz has asked for the wisdom of the Perl Monks concerning the following question:

Howdy Bros. I have some text titles in a database field, some of which have leading/trailing blanks and/or quotes that I want to get rid of. But I only want to update the record if the title was in fact changed.

I have this code for a simplified illustration of the problem

my @items = ('"Title Text Example"', 'Title Text Example', ' Title Tex +t Example ',' "Title Text Example"'); foreach my $title (@items) { $title =~ s/^\s*\"?|\"?\s*$//g; print length($&)," $title\n"; }
Question is, how do I tell if the substitution matched anything? I thought I could check $&, but it's zero length every time through the loop. I don't understand why that is, because it's supposed to give the last successful pattern match, and there are successful matches in every case except the second.

Steve

Comment on Determing if this regex matched
Download Code
Re: Determing if this regex matched
by toolic (Chancellor) on Aug 06, 2011 at 19:40 UTC
    Use an "if" statement to check the return of s/// (returns the number of substitutions made; false otherwise):
    use strict; use warnings; my @items = ('"Title Text Example1"', 'Title Text Example2', ' Title T +ext Example3 ',' "Title Text Example4"'); foreach my $title (@items) { my $match = 0; $match++ if $title =~ s/^[\s"]+//; $match++ if $title =~ s/[\s"]+$//; print "$title.\n" if $match; } __END__ Title Text Example1. Title Text Example3. Title Text Example4.
    Updated to match both begin and end.
      Hey! I had no idea s/// returned anything. Also a more straightforward way to write the regex. Problem is, with the or, the second sub doesn't get executed if the first one matches, so there is still the trailing quote on examples 1 and 4. I suppose one could do
      my @items = ('"Title Text Example"', 'Title Text Example', ' Title Tex +t Example ',' "Title Text Example"'); foreach my $title (@items) { my $changed = 0; if ($title =~ s/^[\s"]+//) { $changed=1; } if ($title =~ s/[\s"]+$//) { $changed=1; } if ($changed) { print "$title\n"; } }
      But that doesn't seem very elegant.
        For the elegant method, try perlretut (and family), "Mastering Regular Expressions," Tutorials, perhaps.

        But -- IMO -- "elegant" is frequently overrated; the real question, I think, is "does it work, consistently?"

        Too much work!
        my @items = ('"Title Text Example"', 'Title Text Example', ' Title Tex +t Example ',' "Title Text Example"'); foreach (@items) { if (s/^[\s"]+// or s/[\s"]+$//) { print "$_\n"; } }

        -- Randal L. Schwartz, Perl hacker

        The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119.

Re: Determing if this regex matched
by toolic (Chancellor) on Aug 07, 2011 at 00:16 UTC
    I thought I could check $&, but it's zero length every time through the loop. I don't understand why that is, because it's supposed to give the last successful pattern match, and there are successful matches in every case except the second.
    The g modifier seems to be clearing $& (or maybe it never gets set in the first place). Add re to your code and you should see the match be successful at first, but it ultimately fails:
    use re 'debug';
    In any case, the g modifier is probably doing you more harm than good. Perhaps a more knowledgeable monk can elaborate on what's going on here. Further reading:

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others musing on the Monastery: (10)
As of 2014-04-23 19:04 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    April first is:







    Results (553 votes), past polls