Сопоставление строки со списком слов - PullRequest
2 голосов
/ 12 ноября 2009

Скажем, у меня есть строка "я застегнул молнию на фезе, и она щелкнула как баа", и у меня есть массив слов (му, баа, почтовый индекс, fjezz, бла), которые я хотел проверить, чтобы увидеть, что они содержатся в строке, есть ли способ сделать это без использования | в регулярном выражении или итерации по каждому слову?

ТИА

Ответы [ 3 ]

7 голосов
/ 12 ноября 2009

Если вы используете Perl 5.10, вы можете использовать оператор smart match :

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

Выше будет проверять равенство (эквивалентно grep $_ eq $str, @words). Если вы хотите соответствовать регулярному выражению, вы можете использовать

if ( @words ~~ /$str/ )

В противном случае вы застряли с grep или first из List :: Util :

if ( grep { $str =~ /$_/ } @words ) { 
    ...
}
0 голосов
/ 15 декабря 2015

Я бы использовал 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

Если вы ищете только частичное совпадение слов в $str, удалите утверждения границы слова \b из регулярного выражения, т.е. замените соответствующую строку выше следующим кодом:

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

и он выдаст:

baa,zip

Если вы хотите, чтобы слова в исходной строке '$ str' совпадали, используйте map и измените регулярное выражение следующим образом:

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

выведет:

baa,zipped

Я также хочу упомянуть оператора ~~, как описано в принятом ответе. Если вы используете хотя бы Perl 5.10.1, вы можете использовать оператор smart match , чтобы найти всего слова соответствий. Следующий код сопоставляет каждое слово из строки $str со списком слов @words. Smartmatch сделает сравнение на основе равенства строк:

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

и вывод:

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

Оператор smartmatch ~~ впервые был доступен в Perl 5.10.1. Начиная с Perl 5.18, smartmatch был помечен как экспериментальный , и если вы используете его, будет выдано предупреждение об этом. Кроме того, поведение smartmatch изменилось между 5.10.0 и 5.10.1. Пример кода, приведенный в « принятый ответ », основан на устаревшем синтаксисе 5.10.0 (см. Комментарий dreagtun).

Примечание: Поэтому вы можете рассматривать smartmatching как "нестабильную" функцию Perl.

PS: Сначала я переписал принятый ответ, но мои изменения были отклонены как слишком радикальные. Поэтому я разместил свой ответ.

0 голосов
/ 12 ноября 2009

Учитывая ваше желание извлечь совпадения, как вы указали в комментарии к ответу @ 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

Или вы хотите, чтобы слова в оригинальном предложении совпадали?

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";

Выход:

zipped baa
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...