Why does Perl this program fail to print "Success" when the regex match succeeds?
I am still a beginner with Perl, so please bear with me. This is the situation I'm experiencing:
$var = "AB1234567";
$num = "1234567";
next if $var =~ /$num/;
print "Success!\n";
Now, my understanding is that it should print "Success!\n", but in reality it doesn't. However, if I change the regex to next if $var =~ /"$num"/;
, this will actually print "Suc开发者_如何学编程cess!\n".
However, if I change it to $var = "AB123456";
, the original regex will work fine.
I understand that when enclosing strings using double quotations, it will dereference interpolate the variable. However, should it not be true in the case of regex? I've done regex using variables without quotations and it worked fine.
Thanks for your help!
EDIT:
I left out semi-colons in my example, but my original problem still stands.
EDIT:
I really should've just copied/pasted. I made a typo and used continue if
instead of next if
. Again, my problem still exists.
I think you are confused on what continue
does. I'm not really sure of what you are trying to do here, but generally continue
will break out of an if-block or go to the next iteration of a for-loop, while-loop, etc. When the pattern does match, continue
is actually skipping over the print statement. When you change the value of $var
, it no longer matches and the print statement is reached.
Try this:
$var = "AB1234567"
$num = "1234567"
print "Success!\n" if $var =~ /$num/;
Randy
I don't think so. This works for me:
$var = "AB1234567";
$num = "1234567";
print "Success!\n" if $var =~ /$num/;
It is either something with your continue statement or the fact that you are missing semicolons in the variable assignments (your example doesn't even run for me....).
Let's look at your code:
$var = "AB1234567";
$num = "1234567";
next if $var =~ /$num/;
print "Success!\n";
I am assuming this is in the body of some loop. When you say
next if $var =~ /$num/;
You are saying "go back and execute the loop body for the next iteration, skipping any following statements in the look body if $var
matches /$num/
". When $var
does indeed match /$num/
, the program does exactly what you asked for and skips the print
statement.
On the other hand, when you use $var =~ /"$num"/
, the pattern on the right hand side becomes /"1234567"/
. Now, the conditional in next if $var =~ /"$num"/
cannot succeed. And, your program prints "Success"
because the match failed.
#!/usr/bin/perl
use strict; use warnings;
use re 'debug';
my $num = "1234567";
for my $var ( qw( AB1234567 ) ) {
next if $var =~ /$num/;
print "Success!\n";
}
Output:
Compiling REx "1234567" Final program: 1: EXACT (4) 4: END (0) anchored "1234567" at 0 (checking anchored isall) minlen 7 Guessing start of match in sv for REx "1234567" against "AB1234567" Found anchored substr "1234567" at offset 2... Starting position does not contradict /^/m... Guessed: match at offset 2 Freeing REx: "1234567"
Now, let's use /"$num"/
as the pattern:
#!/usr/bin/perl
use strict; use warnings;
use re 'debug';
my $num = "1234567";
for my $var ( qw( AB1234567 ) ) {
next if $var =~ /"$num"/;
print "Success!\n";
}
Output:
Compiling REx "%"1234567%"" Final program: 1: EXACT (5) 5: END (0) anchored "%"1234567%"" at 0 (checking anchored isall) minlen 9 Guessing start of match in sv for REx "%"1234567%"" against "AB1234567" Did not find anchored substr "%"1234567%""... Match rejected by optimizer Success! Freeing REx: "%"1234567%""
Your code prints Success! when the match fails.
See also perldoc perlsyn:
The
next
command starts the next iteration of the loop:
LINE: while (<STDIN>) {
next LINE if /^#/; # discard comments
...
}
http://perldoc.perl.org/functions/index.html
C:>perl -e "$x='abc'; $y='bc'; print 'yes' if index($x,$y)>0;"
yes
C:>perl -e "$x='abc'; $y='bc'; print 'yes' if $x =~ /$y/"
yes
If (as is implied) the code is in a loop, you might be interested in qr{}
in http://perldoc.perl.org/perlop.html#Regexp-Quote-Like-Operators
Your code says "If this variable matches this regular expression, do nothing. Otherwise, print Success!
.". I doubt that's what you meant for it to do.
Adding the quotation marks does not affect whether the variable is interpolated at all. What it does do is cause the regular expression match to fail. Since the match fails, the next
[1] is not executing and execution reaches the print statement and Success!
is printed.
The problem with your code is not at all related to regular expressions or to variable interpolation into regular expressions or to quotation marks appearing inside regular expressions. It is a simple logic error of an inverted conditional.
Try replacing the third line with
next unless $var =~ /$num/;
to see what happens when you simply invert the logic of your code to what you probably intended.
[1]: or continue
, depending on which version of your code one is looking at
精彩评论