简体   繁体   English

将字符串与单词列表匹配

[英]Matching a string against a list of words

Say I have the string "i zipped the fezz and it blipped like a baa" and I have an array of words (moo, baa, zip, fjezz, blaa) that I wanted to test to see it they're contained in the string, is there a way of doing so without either using | 假设我有一个字符串“我压缩了毛毛,然后像baa一样突然跳动”,并且我想测试一下包含在字符串中的一系列单词(moo,baa,zip,fjezz,blaa) ,有没有一种方法可以不使用| in the regex or iterating over each word? 在正则表达式中还是遍历每个单词?

TIA TIA

If you're using Perl 5.10, you can use the smart match operator: 如果您使用的是Perl 5.10,则可以使用智能匹配运算符:

my @words = qw/moo bar zip fjezz blaa/;
if ( @words ~~ $str ) { 
    # it's there
}

The above will do an equality check (equivalent to grep $_ eq $str, @words ). 上面将进行相等性检查(相当于grep $_ eq $str, @words )。 If you want a regex match, you can use 如果要进行正则表达式匹配,可以使用

if ( @words ~~ /$str/ )

Otherwise, you're stuck with grep or first from List::Util : 否则,您将陷入grep或从List :: Util first陷入困境:

if ( grep { $str =~ /$_/ } @words ) { 
    ...
}

Given your desire to extract the matches as you indicate in a comment to @friedo's answer, I am confused as to why you want to avoid alternation: 鉴于您希望像在对@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";

Output: 输出:

zip baa

Or, do you want the words in the original sentence that match? 或者,您想要原始句子中的单词是否匹配?

use strict; use warnings;

use Regex::PreSuf;

my $re = presuf(qw(moo baa zip fjezz blaa));

my $str = 'i zipped the fezz and it blipped like a baa';

my @matches = grep { /$re/ } split /\s+/, $str;

print "@matches\n";

Output: 输出:

zipped baa

I'd use grep or map and a regular expression to find matches. 我会使用grepmap和一个正则表达式来查找匹配项。 This brings greater control and flexibility about the matching condition. 这为匹配条件带来了更大的控制力和灵活性。 For example the following code checks if any of the words contained in the list @words is found as an entire word in the string $str : 例如,以下代码检查列表@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";
}

will output: 将输出:

baa

If you are only looking for partial word matches in $str , drop the word boundary assertions \\b from the regular expression, ie replace the respective line above with the following code: 如果仅在$str查找部分单词匹配项 ,请从正则表达式中删除单词边界断言\\b ,即用以下代码替换上面的相应行:

my @found = grep { $str =~ /$_/ } @words;

and it will output: 它会输出:

baa,zip

If you rather want the words in the original string '$str' that match, use map and modify the regular expression as follows: 如果您希望原始字符串 '$ str'中的单词匹配,请使用map并如下修改正则表达式:

my @found = map { $str =~ /(\b\w*?$_\w*?\b)/ ? $1 : () ; } @words;

will output: 将输出:

baa,zipped

I also want to mention the operator ~~ as it described in the accepted answer. 我也想提到操作员~~如公认答案中所述。 If you're using at least Perl 5.10.1, you can use the smart match operator to find entire word matches. 如果您至少使用Perl 5.10.1,则可以使用智能匹配运算符查找整个单词匹配。 The following code smartmatches each word from string $str against the list of words @words . 以下代码将字符串$str中的每个单词与单词@words列表@words The smartmatch will do a comparison based on string equality: smartmatch将基于字符串相等性进行比较:

my @found = grep { $_ ~~ @words } split(/\s+/, $str) ;

and output: 并输出:

Smartmatch is experimental at ./a.pl line 7.
baa

The smartmatch operator ~~ was first available in Perl 5.10.1. smartmatch运算符~~最早在Perl 5.10.1中可用。 Starting with Perl 5.18, smartmatch has been marked as experimental and if you use it, a warning will be issued to this effect. 从Perl 5.18开始, smartmatch已被标记为实验性的 ,如果您使用它,将会对此发出警告。 Additionally, smartmatch behavior has changed between 5.10.0 and 5.10.1. 此外,智能匹配行为已在5.10.0和5.10.1之间更改。 The code example provided in the " accepted answer " is based on 5.10.0 syntax which is obsolete (see dreagtun's comment). “已接受的答案 ”中提供的代码示例基于过时的5.10.0语法(请参见dreagtun的注释)。

Note: You therefore might consider smartmatching as a "non stable" Perl feature. 注意:因此,您可以将智能匹配视为“不稳定”的Perl功能。

PS: At first, I rewrote the accepted answer but my changes were rejected as being too drastic. PS:起初,我改写了接受的答案,但是我的更改因为过于激烈而被拒绝。 Therefore I posted my own answer. 因此,我发表了自己的答案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM