Regex 将字符串与单词列表匹配
假设我有一个字符串“我压缩了fezz,它像一个baa一样闪烁”,我有一个单词数组(moo,baa,zip,fjezz,blaa),我想测试它们是否包含在字符串中,有没有一种不用在正则表达式中使用|或迭代每个单词的方法Regex 将字符串与单词列表匹配,regex,perl,arrays,Regex,Perl,Arrays,假设我有一个字符串“我压缩了fezz,它像一个baa一样闪烁”,我有一个单词数组(moo,baa,zip,fjezz,blaa),我想测试它们是否包含在字符串中,有没有一种不用在正则表达式中使用|或迭代每个单词的方法 TIA如果您使用的是Perl 5.10,则可以使用以下运算符: my @words = qw/moo bar zip fjezz blaa/; if ( @words ~~ $str ) { # it's there } 上述内容将执行相等性检查(相当于grep$\ue
TIA如果您使用的是Perl 5.10,则可以使用以下运算符:
my @words = qw/moo bar zip fjezz blaa/;
if ( @words ~~ $str ) {
# it's there
}
上述内容将执行相等性检查(相当于grep$\ueq$str,@words
)。如果需要正则表达式匹配,可以使用
if ( @words ~~ /$str/ )
否则,您将无法使用grep
或first
来自:
考虑到您在对@friedo答案的评论中指出的提取匹配项的愿望,我不明白您为什么要避免替换:
use strict; use warnings;
use Regex::PreSuf;
my $str = 'i zipped the fezz and it blipped like a baa';
my $re = presuf(qw(moo baa zip fjezz blaa));
my @matches = $str =~ /($re)/g;
print "@matches\n";
输出:
zip baa
zipped baa
输出:
zip baa
zipped baa
拉链baa
我会使用
grep
或map
和正则表达式来查找匹配项。这为匹配条件带来了更大的控制和灵活性。例如,下面的代码检查列表@words
中包含的任何单词是否在字符串$str
中被发现为一个完整单词:
use strict; use warnings;
my $str = "i zipped the fezz and it blipped like a baa";
my @words = qw/moo baa zip fjezz blaa/;
my @found = grep { $str =~ /\b$_\b/ } @words;
if ( @found ) {
print join(",", @found) . "\n";
}
将输出:
baa
baa,zip
baa,zipped
如果您仅在$str
中查找部分单词匹配,请从正则表达式中删除单词边界断言\b
,即用以下代码替换上面的相应行:
my @found = grep { $str =~ /$_/ } @words;
它将输出:
baa
baa,zip
baa,zipped
如果希望原始字符串“$str”中的单词匹配,请使用map
并按如下方式修改正则表达式:
my @found = map { $str =~ /(\b\w*?$_\w*?\b)/ ? $1 : () ; } @words;
将输出:
baa
baa,zip
baa,zipped
我还想提到操作员~
,如接受答案中所述。如果您至少使用Perl 5.10.1,那么可以使用操作符查找整个单词的匹配项。下面的代码将字符串$str
中的每个单词与单词列表@words
匹配。smartmatch将根据字符串相等性进行比较:
my @found = grep { $_ ~~ @words } split(/\s+/, $str) ;
和输出:
Smartmatch is experimental at ./a.pl line 7.
baa
smartmatch操作符~
首次在Perl 5.10.1中提供。从Perl5.18开始,如果您使用它,就会发出警告。此外,smartmatch行为在5.10.0和5.10.1之间发生了变化。“接受答案”中提供的代码示例基于过时的5.10.0语法(参见dreagtun的注释)
<强>注释:,因此您可以将StasperMatpert视为“非稳定”Perl特性。
PS:起初,我重写了被接受的答案,但我的修改被拒绝,因为修改过于激烈。因此,我发布了我自己的答案。
grep{$str=~/$\u/}@words
应该是grep{$\u=~/$str/}@words
使用grep时,你还能提取匹配项吗?i、 e.如果(grep{$str=~/(\d+)(${)/}@words){找到“1:$1\n2:$2\n”}快速尝试似乎不起作用。@Sparkles\d+
是从哪里来的?@Sparles和$1
和$2
在grep
检查完与@words
的每个元素的匹配后,智能匹配会有一些变化。例如,if(@words~~$str)将不再工作。它需要是if($str~~@words)。奇怪的是(@words~~/$str/)仍然有效!ref:&Regex::presf不应在5.10及以上版本中使用(可能非常长的列表除外);内置的trie处理速度要快得多。