Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask
 
PerlMonks  

Re^4: Likely trivial regex question

by moodywoody (Novice)
on Nov 09, 2011 at 10:35 UTC ( [id://937026]=note: print w/replies, xml ) Need Help??


in reply to Re^3: Likely trivial regex question
in thread Likely trivial regex question

Hi graff,

thanks for your efforts. As it happens I'm particularly interested in the part about which you wrote that you cannot explain it either (optional grouping not captured).

As a workaround I've written to regexes coupled with if:
my $re1 = qr/beer=(\d{2}).*chips=(\d{3})/; my $re2 = qr/vodka=(\d{2})/; if ( $str =~ /$re1 ) { my $m1 = $1; my $m2 = $2; if ( $str =~ /$re2/ ) { #use that capture and go on... } }


This does exactly what I want it to do; it's just that I'd like to learn if it's possible to achieve with a single regex. And if not, then why?

While reading up and googling this I realized that I basically do not understand much about greedy/non-greedy quantifier and/or optional groups.

For example I am also puzzled why
"cat:dog" =~ /(cat)*/;
captures "cat", but
"dog:cat" =~ /(cat)*/;
doesn't.

Cheers

Replies are listed 'Best First'.
Re^5: Likely trivial regex question
by ww (Archbishop) on Nov 09, 2011 at 12:38 UTC
    Because in the case of "dog:cat" =~ /(cat)*/;, the "*" quantifies the match to "zero or more" and the first match (at the leading "dog") is "cat" zero times.

    Here's an illustration that beats to death that aspect of your issue.

    #!/usr/bin/perl use Modern::Perl; my $str0 = "0 dog:cat" =~ /(cat)*/; say "\$str0 $str0"; # 1 -- original replaced by scal +ar value my $str1 = "1 dog:cat"; say "\$str1: $str1"; if ($str1 =~ /(cat)*/ ) { my $capture = $1; say "matched |$capture| in \$str1 ($str1) using * quantifier in re +gex"; # see output: uninit $capture }else{ say "no match in \$str1 ($str1) using regex with * quantifier"; } my $str2 = "2 dog:cat"; if ($str2 =~ /(cat)/ ) { my $capture = $1; say "matched |$capture| in \$str2 ($str2) using regex without quan +tifier"; }else{ say "no match in \$str2 ($str2) using regex without quantifier"; } say "-" x10; my $str3 = "3 cat:dog" =~ /(cat)/; say "\$str3: $str3"; # 1 -- original replaced by scal +ar value my $str4 = "4 cat:dog"; if ($str4 =~ /(cat)/ ) { my $capture = $1; say "matched |$capture| in \$str4 ($str4) using regex without quan +tifier"; }else{ say "fubar on |$str4| using regex without quantifier"; } =head $str0 1 $str1: 1 dog:cat Use of uninitialized value $capture in concatenation (.) or string at +F:\_wo\junk20111109.pl line 11. matched || in $str1 (1 dog:cat) using * quantifier in regex matched |cat| in $str2 (2 dog:cat) using regex without quantifier ---------- $str3: 1 matched |cat| in $str4 (4 cat:dog) using regex without quantifier =cut
    (This in no way deprecates choroba's discussion but is offered in the hope that the simpler example here may be more accessible).
Re^5: Likely trivial regex question
by choroba (Cardinal) on Nov 09, 2011 at 11:00 UTC
    See my reply to graff: Re^4: Likely trivial regex question. To clarify your examples with "cat", use the /g modifier in list context to understand:
    perl -E 'say for "cat:dog" =~ /(cat)*/g;say "=";say for "dog:cat" =~ / +(cat)*/g'

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others surveying the Monastery: (4)
As of 2024-04-24 04:00 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found