Как сопоставить слова определенной длины с регулярным выражением в Perl? - PullRequest
0 голосов
/ 30 августа 2009

Я хочу найти слово, которое состоит всего из трех букв и начинается с т и заканчивается е. Есть ли другой способ, кроме того, что я сделал:

open (FH, "alice.txt");
@lines = <FH>;
close(FH);

foreach $words(@lines)
{
   if($words =~ m/ t.e /g)
   {
     print $words," ";
   }
}

Также я хотел найти слова длиной более 3 букв. Как я могу этого достичь? слово может иметь что угодно, кроме пробелов. Любое слово не обязательно должно начинаться с т или заканчиваться на е. Любое слово длиной более 3 букв.

Ответы [ 5 ]

5 голосов
/ 30 августа 2009

Итак, ваше регулярное выражение не сможет подать слова в начале и конце строк. Вот для чего утверждение \b:

#!/use/bin/perl

use strict;
use warnings;

use Text::Wrap;

my $file = "alice.txt";

open my $fh, "<", $file
    or die "could not open $file: $!";

my @words;
while (<$fh>) {
    push @words, /\b(t\we)\b/g;
}
print "three letter words that start with t and end with e:\n",
    wrap "\t", "\t", "@words\n";

Вы можете найти четырехбуквенные слова, просто ища все, что является символом слова, который имеет более 3 символов. Класс символов \w совпадает с символами слова, а квантификатор {4,}, скажем, соответствует предыдущему шаблону 4 или более раз. Соедините их с утверждением границы слова, и вы получите /\b\S{4,}\b/:

#!/use/bin/perl

use strict;
use warnings;

use Text::Wrap;

my $file = "alice.txt";

open my $fh, "<", $file
    or die "could not open $file: $!";

my @three;
my @four;
while (<$fh>) {
    push @three, /\b(t\we)\b/g;
    push @four, /\b(\w{4,})\b/g;
}
print "three letter words that start with t and end with e:\n",
    wrap("\t", "\t", "@three\n"),
    "four letter words:\n",
    wrap "\t", "\t", "@four\n";

Вы можете использовать [[:alpha:]] вместо \w, если не хотите сопоставлять такие вещи, как "t0e".

3 голосов
/ 30 августа 2009

Ваш код в порядке. Вы можете изменить буквальное пространство на \b (граница слова).

Если вы хотите сопоставить несколько символов между t и e, используйте \w+ вместо ..

2 голосов
/ 30 августа 2009

Попробуйте использовать \bt\w+e\b в качестве регулярного выражения. Это находит все целые слова, которые начинаются с буквы «t» и заканчиваются буквой «e», и имеют по крайней мере одну букву или цифру между ними. Таким образом, будут сопоставлены слова «the» и «tattle», как и «t999e».

1 голос
/ 01 сентября 2009

Хотя одним из регулярных выражений может быть ваше решение для этой конкретной проблемы, откажитесь от идеи, что один регулярное выражение должно выполнять всю проверку. Иногда проще разбить условия и разобраться с ними по отдельности:

if( 3 == length( $word ) and $word =~ m/$regex/ ) { ... }

Я думаю, что легче понять твои намерения, когда ты пишешь это так. Вы видите ограничение по длине и ограничение по содержанию.

В зависимости от того, что я делал, я мог бы вместо этого создать конвейер (иногда потому, что интересно программировать, притворяясь, что никто никогда не изобретал if ()). Я думаю, что этот конвейер лучше отражает то, как люди думают о проблеме поэтапно:

open my( $fh ), '<', 'alice.txt' or die ...;

my @matches = 
              grep { /$regex/ }     # select only matching words
              grep { 3 == length }  # select only three character lines
              map  { chomp; $_ }
              <$fh>;

Хорошая вещь в этом способе состоит в том, что легко поворачивать шаги. Вы говорите, что также хотите попробовать его с любым словом, содержащим более трех символов. Я опускаю фильтр регулярных выражений и настраиваю фильтр длины:

my @matches = 
              grep { 3 < length }  # select only those with more than three characters
              map  { chomp; $_ }
              <$fh>;
0 голосов
/ 30 августа 2009

Найти слова типа te можно с помощью:

/\b(t\Se)\b/

Поиск более длинных слов (при условии, что определение: слово может содержать любые непустые символы):

/\b(\S{4,})\b/
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...