我有两个问题,但也很容易回答。可能只是一个新手问题。谷歌几乎没有。
首先:如何在数组中放置Perl匹配运算符? 例如所有这些字符:
{}[]()^$.|*+?\
然后使用foreach?
其次,如果你有这个:
@array = qw(The $ quick ? brown | fox jumps over the lazy dog);
$string = "\? brown \|";
@new_array = grep(/$string/,@array);
如果在@array中正确查找$ string,如果@array是一些文本,例如包含美元符号,问号等?如果你搜索正则表达式字符,它将变成运算符。如果你这样做:
$string =~ s/\$/\$/gi;
当然会有相同的结果。
提前致谢。
答案 0 :(得分:3)
这里的问题是:
$string = "\? brown \|";
只是一种误导性的写作方式:
$string = "? brown |";
最好的修复方法是(选项1)根本不使用字符串,而是使用模式对象:
$pat = qr/\? brown \|/;
@new_array = grep(/$pat/,@array);
或(2)在创建模式时使用\Q
“引用”字符串中的任何正则表达式元字符:
$string = "? brown |";
@new_array = grep(/\Q$string/,@array);
如果不这样做,您可以通过编写以下任何内容来确保您的字符串最终实际包含\? brown \|
(而不仅仅是? brown |
):
$string = "\\? brown \\|"; # option 3
$string = '\? brown \|'; # option 4
$string = "\Q\? brown \|"; # option 5
答案 1 :(得分:0)
除了合适的引用之外,搜索匹配的字符串不需要特别小心或转义。匹配模式只需要按字面意思进行转义即可进行转义,但如果存在附加引用则需要对其进行插值保护。有关引用的评论,请参见最后。
my @spec_ch = qw({ } [ ] ( ) ^ $ . | * + ? \ );
my @matched = grep { /\$|\?/ } @spec_ch;
print "@matched\n";
打印
$ ?
您的实际示例,仅缩短并使用foreach
(有关grep
的评论,请参见下文)。
my @patterns = ('\?', 'brown', '\|', 'fox'); # or qw(\? brown \| fox);
my $string = '? brown |'; # or q(? brown |);
foreach my $patt (@patterns) {
my ($match) = $string =~ m/($patt)/;
print "$match\n" if $match;
}
打印
? brown |
您的示例转过来,使用包含单词和转义字符的模式
my $str = q(The $ quick ? brown | fox jumps over the lazy dog);
my $patt = qr(\? brown \|); # or simply '\? brown \|'
my ($match) = $str =~ m/($patt)/;
print "$match\n";
打印
? brown |
您的 grep
示例的问题在于它尝试匹配相反的方式 - 变量$string
用作模式,而数组中的单词是搜索匹配的字符串。
grep { $_ =~ m/$string/ } @array;
# regex syntax: $text =~ m/$pattern/, so above $_ is string, $string is pattern
因此$_
依次接受值The
,$
,quick
(等),并搜索模式$string
在里面。上面的foreach
示例可以解释您的想法。
双引号可能会出现问题,因为它们会进行插值,然后你必须进行额外的转义。使用单引号然后将转义的特殊字符带入正则表达式,无需任何解释。
运算符qw
和q
不进行插值。请参阅Quote and Quote-like Operators in perlop
。