Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?
 
PerlMonks  

comment on

( [id://3333]=superdoc: print w/replies, xml ) Need Help??

You will find the answer to your question in "Regexp Quote-Like Operators" in perlop - basically, different regex operations have different return values in different contexts. See also perlretut for a tutorial.

Operation Context () Capturing
Groups
Return Value on Match
(and notes on behavior)
Return Value on Failure Example
m// scalar - true false
my $x = "foobar"=~/[aeiou]/; # => $x is true my $y = "foobar"=~/[xyz]/; # => $y is false
m//g scalar - true
(each execution of m//g finds the next match,
see "Global matching" in perlretut)
false if there is no further match
my $str = "foobar"; my $x = $str=~/[aeiou]/g; # matches first "o" => $x is true, pos($str) is 2 $x = $str=~/[aeiou]/g; # matches second "o" => $x is true, pos($str) is 3 $x = $str=~/[aeiou]/g; # matches "a" => $x is true, pos($str) is 5 $x = $str=~/[aeiou]/g; # no more matches => $x is false, pos($str) is undef
m// list no the list (1) the empty list ()
my ($x) = "foobar"=~/[aeiou]/; # => $x is 1
m//g list no a list of all the matched strings, as if there were parentheses around the whole pattern the empty list ()
my ($x,$y,$z) = "foobar"=~/[aeiou]/g; # => $x is "o", $y is "o", $z is "a"
m// list yes a list consisting of the subexpressions matched by the parentheses in the pattern, that is, ($1, $2, $3...) the empty list ()
my ($x,$y) = "foobar"=~/([aeiou])(.)/; # => $x is "o", $y is "o"
m//g list yes a list of the substrings matched by any capturing parentheses in the regular expression, that is, ($1, $2...) repeated for each match the empty list ()
my ($w,$x,$y,$z) = "foobar"=~/([aeiou])(.)/g; # => $w is "o", $x is "o", $y is "a", $z is "r"
s/// - - the number of substitutions made false
my $x = "foobar"; my $y = $x=~s/[aeiou]/x/g; # => $y is 3
s///r - - a copy of the original string with substitution(s) applied
(available since Perl 5.14)
the original string
my $x = "foobar"=~s/[aeiou]/x/gr; # => $x is "fxxbxr"

In this table, "true" and "false" refer to Perl's notion of Truth and Falsehood. Remember not to rely on any of the capture variables like $1, $2, etc. unless the match succeeds!

In my $foo = "bar"=~/a/;, the right-hand side of the assignment ("bar"=~/a/) is in scalar context. In my ($foo) = "bar"=~/a/; or my @foo = "bar"=~/a/;, the right-hand side is in list context. That's why, in your example, you need those parens in ($value): because you want the matching operation to return the contents of the capture group.

Note that your expressions can be slightly simplified, not all the parens you showed are needed:

my ($value) = $row =~ /.*,(.*)/; # and $row =~ s/,[^,]*$//;

A few additional comments on your code:

  • ($row =~ s/,[^,]*$//); # gets substring before the last comma - this comment isn't quite right or at least potentially misleading, since it deletes the string before after and including the last comma.
  • /.*,(.*)/ matches any comma anywhere in the string, for simple input strings it may behave correctly, but I'd strongly recommend coding more defensively and writing it like your second expression: my ($value) = $row=~/,([^,]*)$/; - the $ anchor makes sure that the regex only matches the last comma and what follows it (unless you use the /m modifier, since it changes the meaning of $).
  • While the use of Scalar::Util's looks_like_number is often a good idea, note that if you don't mind being a little more restrictive, Regexp::Common (or a hand-written regex) would allow you to combine the two regular expressions:
    use Regexp::Common qw/number/; my $row = "a,b,c,d,15"; if ( $row=~s/,($RE{num}{real})$// ) { print "matched <$1>\n"; } print "row is now <$row>\n"; __END__ matched <15> row is now <a,b,c,d>
  • If this is a CSV file, consider using Text::CSV (also install Text::CSV_XS for speed)

Update: Added s///r to the table and added a few more doc links. A few other edits and updates. 2019-02-16: Added "Return Value on Failure" column to table, and a few other small updates. 2019-08-17: Updated the link to "Truth and Falsehood".


In reply to Re: difference in regex by haukex
in thread difference in regex by ovedpo15

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":



  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or How to display code and escape characters are good places to start.
Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Chatterbox?
and the web crawler heard nothing...

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

    No recent polls found