Regex 将字符串与单词列表匹配

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

假设我有一个字符串“我压缩了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$\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处理速度要快得多。