Regex 在Perl';中插入变量时,如何转义元字符;谁是接线员?
假设我有一个包含我试图匹配的行的文件:Regex 在Perl';中插入变量时,如何转义元字符;谁是接线员?,regex,perl,variables,interpolation,Regex,Perl,Variables,Interpolation,假设我有一个包含我试图匹配的行的文件: foo quux bar 在我的代码中,我有另一个数组: foo baz quux 假设我们遍历该文件,调用每个元素$word,以及我们要检查的内部列表@arr if( grep {$_ =~ m/^$word$/i} @arr) 这是正确的,但是在文件中有一个测试用例fo.的情况下,作为正则表达式中的通配符操作,fo.然后匹配foo,这是不可接受的 这当然是因为Perl将变量插入正则表达式中 问题是: 如何强制Perl按字面意思使用变量?Quote
foo
quux
bar
在我的代码中,我有另一个数组:
foo
baz
quux
假设我们遍历该文件,调用每个元素$word
,以及我们要检查的内部列表@arr
if( grep {$_ =~ m/^$word$/i} @arr)
这是正确的,但是在文件中有一个测试用例fo.
的情况下,
作为正则表达式中的通配符操作,fo.
然后匹配foo
,这是不可接受的
这当然是因为Perl将变量插入正则表达式中
问题是:
如何强制Perl按字面意思使用变量?Quotemeta 返回EXPR的值,并将所有非“word”字符反斜杠
使用
\Q..\E
在变量值插值后直接转义perl字符串中的特殊符号:
if( grep {$_ =~ m/^\Q$word\E$/i} @arr)
正确答案是-不要使用regexp。我并不是说regexp不好,但将它们用于(等于)简单的相等性检查是过分的 使用:
grep{lc($)eq lc($word)}@arr
并快乐。从的答案:
我们不必将模式硬编码到匹配操作符(或任何其他与正则表达式一起工作的东西)中。我们可以将该模式放在一个变量中供以后使用 匹配运算符是双引号上下文,因此可以像双引号字符串一样插入变量。在本例中,将正则表达式作为用户输入读取,并将其存储在$regex中。一旦在$regex中有了模式,就可以在match操作符中使用该变量
chomp( my $regex = <STDIN> );
if( $string =~ m/$regex/ ) { ... }
当Perl编译正则表达式时,它将括号视为内存匹配的开始。当它找不到右括号时,它会抱怨:
Unmatched ( in regex; marked by <-- HERE in m/Unmatched ( <-- HERE paren/ at script line 3.
我认为在这种情况下你不需要正则表达式,因为你没有匹配模式。您正在寻找您已经知道的字符的文字序列。使用要匹配的值构建一个散列,并使用该散列筛选
@arr
:
open my $fh, '<', $filename or die "...";
my %hash = map { chomp; lc($_), 1 } <$fh>;
foreach my $item ( @arr )
{
next unless exists $hash{ lc($item) };
print "I matched [$item]\n";
}
打开我的$fh,'很好。正则表达式解决方案是旧代码和更复杂代码的残余。请参阅的可能重复。最后一个代码示例中的eval是否在“{…}”中捕获错误,或者“if($string=~m/\Q$input\E/)”中是否也有错误?eval将捕获其块中的所有错误,但就这个问题而言,它捕获了在匹配运算符中看到的显式代码中的错误。然后regexp将类似于“m/^fo\\E\.$/i”。请参见上的\Q
元符号说明,特别注意“abc\Qfoo\tbar$s\Exyz”
相当于“abc”。quotemeta(“foo\tbar$s”)。“xyz”
。
chomp( my $regex = <STDIN> );
$regex = quotemeta( $regex );
if( $string =~ m/$regex/ ) { ... }
chomp( my $regex = <STDIN> );
if( $string =~ m/\Q$regex\E/ ) { ... }
chomp( my $input = <STDIN> );
my $regex = qr/$input/is;
$string =~ m/$regex/ # same as m/$input/is;
chomp( my $input = <STDIN> );
eval {
if( $string =~ m/\Q$input\E/ ) { ... }
};
warn $@ if $@;
my $regex = eval { qr/$input/is };
if( defined $regex ) {
$string =~ m/$regex/;
}
else {
warn $@;
}
open my $fh, '<', $filename or die "...";
my %hash = map { chomp; lc($_), 1 } <$fh>;
foreach my $item ( @arr )
{
next unless exists $hash{ lc($item) };
print "I matched [$item]\n";
}