是使用“||”在禁止子字符串搜索?
Is the use of "||" in a substring search prohibited?
我有一个小的 Perl 脚本,其中包含如下子字符串搜索。
#!/usr/bin/perl
use strict;
use warnings;
my $line = "this && is || a test if && ||";
my $nb_if = findSymbols($line, "if ");
my $nb_and = findSymbols($line, "&&");
my $nb_or = findSymbols($line, "||");
print "\nThe result for this func is $nb_if=if , $nb_and=and, $nb_or=or\n";
sub findSymbols {
my $n = () = ($_[0] =~ m/$_[1]/g);
return $n;
}
应该return:
The result for this func is 1=if , 2=and, 2=or
但是,它 returns:
The result for this func is 1=if , 2=and, 30=or
我不明白我的代码有什么问题。
|
是m//
使用的正则表达式中的交替运算符。您需要使用反斜杠转义每个 |
以匹配文字 |
s.
my $nb_or = findSymbols($line, "\|\|"); # or '\|\|`
(但使用 quotemeta
作为 是一个更好的主意,因为它使您的调用者不必担心应该属于 findSymbols
提供的抽象的一部分的细节.)
使用 quotemeta 转义包含 ||
的正则表达式(以及您传递给函数的任何其他字符)的特殊含义:
sub findSymbols {
my $pat = quotemeta $_[1];
my $n = () = ($_[0] =~ m/$pat/g);
return $n;
}
竖线符(|
)在正则表达式中有特殊含义。它的意思是“或”(匹配左边的事物或右边的事物)。因此,有一个仅由两个管道组成的正则表达式被解释为“匹配一个空字符串或一个空字符串或一个空字符串”——并且匹配字符串中的任何地方(30 次!)
所以你需要停止将管道解释为特殊字符,让它只代表一个实际的管道字符。以下是三种方法:
在创建传递给 findSymbols()
.
的字符串时,使用反斜杠转义管道
# Note: I've also changed "..." to '...'
# to avoid having to double-escape
my $nb_or = findSymbols($line, '\|\|');
使用 quotemeta()
自动转义传递给 findSymbols()
.
的任何字符串中的有问题的字符
my $escaped_regex = quotemeta($_[0]);
my $n = () = ($_[0] =~ m/$escaped_regex/g);
使用 \Q...\E
自动转义正则表达式中使用的任何有问题的字符。
# Note: In this case, the \E isn't actually needed
# as it's at the end of the regex.
my $n = () = ($_[0] =~ m/\Q$_[0]\E/g);
我有一个小的 Perl 脚本,其中包含如下子字符串搜索。
#!/usr/bin/perl
use strict;
use warnings;
my $line = "this && is || a test if && ||";
my $nb_if = findSymbols($line, "if ");
my $nb_and = findSymbols($line, "&&");
my $nb_or = findSymbols($line, "||");
print "\nThe result for this func is $nb_if=if , $nb_and=and, $nb_or=or\n";
sub findSymbols {
my $n = () = ($_[0] =~ m/$_[1]/g);
return $n;
}
应该return:
The result for this func is 1=if , 2=and, 2=or
但是,它 returns:
The result for this func is 1=if , 2=and, 30=or
我不明白我的代码有什么问题。
|
是m//
使用的正则表达式中的交替运算符。您需要使用反斜杠转义每个 |
以匹配文字 |
s.
my $nb_or = findSymbols($line, "\|\|"); # or '\|\|`
(但使用 quotemeta
作为 findSymbols
提供的抽象的一部分的细节.)
使用 quotemeta 转义包含 ||
的正则表达式(以及您传递给函数的任何其他字符)的特殊含义:
sub findSymbols {
my $pat = quotemeta $_[1];
my $n = () = ($_[0] =~ m/$pat/g);
return $n;
}
竖线符(|
)在正则表达式中有特殊含义。它的意思是“或”(匹配左边的事物或右边的事物)。因此,有一个仅由两个管道组成的正则表达式被解释为“匹配一个空字符串或一个空字符串或一个空字符串”——并且匹配字符串中的任何地方(30 次!)
所以你需要停止将管道解释为特殊字符,让它只代表一个实际的管道字符。以下是三种方法:
在创建传递给
的字符串时,使用反斜杠转义管道findSymbols()
.# Note: I've also changed "..." to '...' # to avoid having to double-escape my $nb_or = findSymbols($line, '\|\|');
使用
的任何字符串中的有问题的字符quotemeta()
自动转义传递给findSymbols()
.my $escaped_regex = quotemeta($_[0]); my $n = () = ($_[0] =~ m/$escaped_regex/g);
使用
\Q...\E
自动转义正则表达式中使用的任何有问题的字符。# Note: In this case, the \E isn't actually needed # as it's at the end of the regex. my $n = () = ($_[0] =~ m/\Q$_[0]\E/g);