Perl match only returning “1”. Booleans? Why?

后端 未结 6 886
星月不相逢
星月不相逢 2021-01-18 13:18

This has got to be obvious but I\'m just not seeing it.

I have a documents containing thousands of records just like below:

Row:1 DATA:
[0]37755442
[         


        
相关标签:
6条回答
  • 2021-01-18 13:20

    From perlop, Quote and Quote-Like operators [bits in brackets added by me]:

    /PATTERN/msixpodualgc

    Searches a string for a pattern match, and in scalar context returns true [1] if it succeeds, false [undef] if it fails.

    (Looking at the section on s/// will also be useful ;-)

    Perl just doesn't have a discreet boolean type or true/false aliases so 1 and undef are often used: however, it could very well could be other values without making the documentation incorrect.

    $1 will never be defined because there is no capture group: perhaps $& (aka $MATCH) is desired? (Or better, change the regular expression to have a capture group ;-)

    Happy coding.

    0 讨论(0)
  • 2021-01-18 13:33
    my($foo) = $record=~ /Defect/;
    print STDOUT $foo;
    

    Rather than this you should do

    $record =~ /Defect/;
    my $foo = $&; # Matched portion of the $record.
    

    As your goal seems to be to get the matched portion. The return value is true/false indicating if match was successful or not.

    You may find http://perldoc.perl.org/perlreref.html handy.

    0 讨论(0)
  • 2021-01-18 13:35

    The =~ perl operator takes a string (left operand) and a regular expression (right operand) and matches the string against the RE, returning a boolean value (true or false) depending on whether the re matches.

    Now perl doesn't really have a boolean type -- instead every value (of any type) is treated as either 'true' or 'false' when in a boolean context -- most things are 'true', but the empty string and the special 'undef' value for undefined things are false. So when returning a boolean, it generall uses '1' for true and '' (empty string) for false.

    Now as to your last question, where trying to print $1 prints nothing. Whenever you match a regular expression, perl sets $1, $2 ... to the values of parenthesized subexpressions withing the RE. In your example however, there are NO parenthesized sub expressions, so $1 is always empty. If you change it to

    $record =~ /(Defect)/;
    print STDOUT $1;
    

    You'll get something more like what you expect (Defect if it matches and nothing if it doesn't).

    The most common idiom for regexp matching I generally see is something like:

    if ($string =~ /regexp with () subexpressions/) {
        ... code that uses $1 etc for the subexpressions matched
    } else {
        ... code for when the expression doesn't match at all
    }
    
    0 讨论(0)
  • 2021-01-18 13:36

    If you want the result of a match as "true" or "false", then do the pattern match in scalar context. That's what you did in your first example. You performed a pattern match and assigned the result to the scalar my($foo). So $foo got a "true" or "false" value.

    But if you want to capture the text that matched a part of your pattern, use grouping parentheses and then check the corresponding $ variable. For example, consider the expression:

    $record =~ /(.*)ing/
    

    A match on the word "speaking" will assign "speak" to $1, "listening" will assign "listen" to $1, etc. That's what you are trying to do in your second example. The trouble is that you need to add in the grouping parentheses. "$record =~ /Defect/" will assign nothing to $1 because there are no grouping parentheses in the pattern.

    0 讨论(0)
  • 2021-01-18 13:43

    I think what you really want is to wrap the regex in parentheses:

    my($foo) = $record=~ /(Defect)/;
    

    In list context, the groups are returned, not the match itself. And your original code has no groups.

    0 讨论(0)
  • 2021-01-18 13:46

    You need to use capturing parentheses to actually capture:

    if ($record =~ /(Defect)/ ) {
        print "$1\n";
    }
    
    0 讨论(0)
提交回复
热议问题