我有一個小的 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;
}
它應該回傳:
The result for this func is 1=if , 2=and, 2=or
但是,它回傳:
The result for this func is 1=if , 2=and, 30=or
我不明白我的代碼有什么問題。
uj5u.com熱心網友回復:
使用quotemeta來轉義包含||(以及您傳遞給函式的任何其他字符)的正則運算式的特殊含義:
sub findSymbols {
my $pat = quotemeta $_[1];
my $n = () = ($_[0] =~ m/$pat/g);
return $n;
}
uj5u.com熱心網友回復:
管道字符 ( |) 在正則運算式中具有特殊含義。它的意思是“或”(匹配左邊的東西或右邊的東西)。因此,僅由兩個管道組成的正則運算式被解釋為“匹配空字串或空字串或空字串” - 并且匹配字串中的任何地方(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 中使用正則運算式的更多詳細資訊,請參閱perlretut和perlre。
uj5u.com熱心網友回復:
|是 使用的正則運算式中的交替運算子m//。您需要|使用反斜杠對每個進行轉義以匹配文字|s。
my $nb_or = findSymbols($line, "\\|\\|"); # or '\|\|`
(但是quotemeta按照@toolic 的建議使用是一個更好的主意,因為它使您的呼叫者不必擔心應該是findSymbols.提供的抽象的一部分的細節。)
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/316247.html
標籤:perl
上一篇:Perl可選捕獲組不起作用?
