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

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

Hi All, I have a regular expression in place that does a check on a string coming in from a form. The regular expression is as such : $string =~ m/^(frm)(\w+)(txt)?$/; What I was hoping to accomplish was to have $1, $2, and $3 populated with the values in the brackets. When I run this and the string is something like frmNametxt the $1 gets set to frm, $2 gets set to Nametxt and $3 to nothing. What (if anything) can I do to force the code to evaluate and store txt into $3? If txt is there I want it put into $3. Any help would be most appreciated. Thanks. Rob

Replies are listed 'Best First'.
Re: RegExp Matched Values
by jethro (Monsignor) on Apr 30, 2010 at 13:37 UTC
    Use $string =~ m/^(frm)(\w+?)(txt)?$/;. This works because \w+? tries to match the smallest possible string now

    Note this works only because the string is anchored at the end. Otherwise \w+? would always match only one character and (txt)? the empty string.

      $string =~ m/^(frm)(\w+?)(txt)?$/;

      There's a problem here in that if  'txt' may not be present (as  (txt)? implies) and an overall match is still desired,  $3 will be undefined because the third capture group need not match at all. A different approach will yield an empty string instead.

      >perl -wMstrict -le "for (@ARGV) { m/^(frm)(\w+?)(txt)?$/; print qq{'$_' ($1) ($2) ($3)}; } print '-----------'; for (@ARGV) { m/^(frm)(\w+?)(txt|)$/; print qq{'$_' ($1) ($2) ($3)}; } " frmNametxt frmNameFoo 'frmNametxt' (frm) (Name) (txt) Use of uninitialized value $3 in concatenation (.) or string at ... 'frmNameFoo' (frm) (NameFoo) () ----------- 'frmNametxt' (frm) (Name) (txt) 'frmNameFoo' (frm) (NameFoo) ()
Re: RegExp Matched Values
by AR (Friar) on Apr 30, 2010 at 13:30 UTC

    In this very specific example, you can change the \w+ into the lazy version: \w+?. If you're looking for a solution to a more general problem, this may not be appropriate.