Pau*_*han 12 regex variables perl interpolation
假设我有一个包含我想要匹配的行的文件:
foo
quux
bar
Run Code Online (Sandbox Code Playgroud)
在我的代码中,我有另一个数组:
foo
baz
quux
Run Code Online (Sandbox Code Playgroud)
假设我们遍历文件,调用每个元素$word
,以及我们正在检查的内部列表,@arr
.
if( grep {$_ =~ m/^$word$/i} @arr)
Run Code Online (Sandbox Code Playgroud)
这样可以正常工作,但在某种可能的情况下,我们fo.
在文件中有一个测试用例,它.
在正则表达式中作为通配符操作符运行,fo.
然后匹配foo
,这是不可接受的.
这当然是因为Perl正在将变量插入到正则表达式中.
问题:
如何强制Perl按字面意思使用变量?
Iva*_*uev 33
用于\Q...\E
在变量值插值后直接在perl字符串中转义特殊符号:
if( grep {$_ =~ m/^\Q$word\E$/i} @arr)
Run Code Online (Sandbox Code Playgroud)
bri*_*foy 17
我们不必将模式硬编码到匹配运算符(或其他任何与正则表达式一起使用的代码)中.我们可以将模式放在变量中供以后使用.
匹配运算符是双引号上下文,因此您可以像双引号字符串一样插入变量.在这种情况下,您将正则表达式作为用户输入读取并将其存储在$ regex中.在$ regex中使用该模式后,可以在匹配运算符中使用该变量.
chomp( my $regex = <STDIN> );
if( $string =~ m/$regex/ ) { ... }
Run Code Online (Sandbox Code Playgroud)
$ regex中的任何正则表达式特殊字符仍然是特殊的,并且该模式仍然必须有效或Perl会抱怨.例如,在这种模式中有一个不成对的括号.
my $regex = "Unmatched ( paren";
"Two parens to bind them all" =~ m/$regex/;
Run Code Online (Sandbox Code Playgroud)
当Perl编译正则表达式时,它将括号视为内存匹配的开始.当它没有找到右括号时,它会抱怨:
Unmatched ( in regex; marked by <-- HERE in m/Unmatched ( <-- HERE paren/ at script line 3.
Run Code Online (Sandbox Code Playgroud)
根据我们的情况,您可以通过多种方式解决这个问题.首先,如果您不希望字符串中的任何字符都是特殊字符,则可以在使用字符串之前使用quotemeta对其进行转义.
chomp( my $regex = <STDIN> );
$regex = quotemeta( $regex );
if( $string =~ m/$regex/ ) { ... }
Run Code Online (Sandbox Code Playgroud)
您也可以使用\ Q和\ E序列在匹配运算符中直接执行此操作.\ Q告诉Perl从哪里开始转义特殊字符,\ E告诉它在哪里停止(有关详细信息,请参阅perlop).
chomp( my $regex = <STDIN> );
if( $string =~ m/\Q$regex\E/ ) { ... }
Run Code Online (Sandbox Code Playgroud)
或者,您可以使用qr //,正则表达式引用运算符(有关详细信息,请参阅perlop).它引用并可能编译模式,您可以将正则表达式标志应用于模式.
chomp( my $input = <STDIN> );
my $regex = qr/$input/is;
$string =~ m/$regex/ # same as m/$input/is;
Run Code Online (Sandbox Code Playgroud)
您可能还希望通过在整个事物周围包装一个eval块来捕获任何错误.
chomp( my $input = <STDIN> );
eval {
if( $string =~ m/\Q$input\E/ ) { ... }
};
warn $@ if $@;
Run Code Online (Sandbox Code Playgroud)
要么...
my $regex = eval { qr/$input/is };
if( defined $regex ) {
$string =~ m/$regex/;
}
else {
warn $@;
}
Run Code Online (Sandbox Code Playgroud)
小智 12
正确答案是 - 不要使用正则表达式.我不是说正则表达式是坏的,但是使用它们(等于)简单的相等检查是过度的.
使用:grep { lc($_) eq lc($word) } @arr
并且快乐.
归档时间: |
|
查看次数: |
17109 次 |
最近记录: |