Найти слова в строке - PullRequest
0 голосов
/ 02 марта 2020

Я бы хотел показать в результате три слова «скрытый». Я не знаю, как это сделать. Прямо сейчас, когда я запускаю программу, у меня нет эффекта. Я вижу только мой текст. Как это починить? Я хочу создать простую программу. У меня есть строка, и я хочу показать слова, которые я хочу найти в моем результате.

use strict;
my $text='Try to find the hidden string here! Hidden or hidden';
my $a = m/\bhidden\b/;
if ($text=~ $a) {
   print "I found word: $a";
}
else {
   print "No match, sorry.\n";
}

Ответы [ 2 ]

1 голос
/ 02 марта 2020

Давайте посмотрим, как мы можем отладить эту проблему.

Ваш первый шаг должен состоять в добавлении use warnings в ваш код. Вы должны всегда включать как use strict, так и use warnings. Они как сети безопасности Perl и только безрассудный программист кодирует без них.

#!/usr/bin/perl

use strict;
use warnings; # ADDED THIS

my $text='Try to find the hidden string here! Hidden or hidden';
my $a = m/\bhidden\b/;
if ($text=~ $a) {
   print "I found word: $a";
}
else {
   print "No match, sorry.\n";
}

Теперь мы получаем предупреждение:

Использование неинициализированного значения $ _ in соответствие шаблону (m //) в строке test_re 8.

Строка 8 выглядит следующим образом:

if ($text=~ $a) {

Итак, давайте посмотрим, что находится в $a (в качестве отступления - пожалуйста не используйте $a в качестве имени переменной. Во-первых, это ужасное обобщенное имя c, а во-вторых, Perl использует его как специальную переменную в функции sort):

#!/usr/bin/perl

use strict;
use warnings;
use feature 'say'; # ADDED THIS

my $text='Try to find the hidden string here! Hidden or hidden';
my $a = m/\bhidden\b/;
say "\$a is [$a]"; # ADDED THIS
if ($text=~ $a) {
   print "I found word: $a";
}
else {
   print "No match, sorry.\n";
}

Теперь, как и наше предупреждение, мы получаем следующий вывод:

$a is []

Я не думаю, что вы ожидаете, что $a будет пустым в этот момент , ты? Мы можем go далее и определить, является ли это пустой строкой или неопределенным значением.

#!/usr/bin/perl

use strict;
use warnings;
use feature 'say';

my $text='Try to find the hidden string here! Hidden or hidden';
my $a = m/\bhidden\b/;
say "\$a is [$a]";
say "\$a is ", (defined $a ? 'defined' : 'undefined'); # ADDED THIS
if ($text=~ $a) {
   print "I found word: $a";
}
else {
   print "No match, sorry.\n";
}

И мы видим:

$a is defined

Так что это пустое строка. Что вы ожидаете, что это будет?

Вот где это установлено?

my $a = m/\bhidden\b/;

Я не уверен, что вы ожидали, что это будет делать, но на самом деле это означает "матч \bhidden\b и присвойте результат матча $a ". И что это соответствует этому регулярному выражению? Ну, m/.../ matches the contents of $ `по умолчанию. (Это, кстати, объясняет наше первоначальное предупреждение «неинициализированное значение $ » - Perl только что неправильно набрал номер строки на единицу.)

Так что на самом деле в этой строке происходит то, что Perl пытается сопоставить \bhidden\b с $_. Это терпит неудачу (так как $_ не определено), и совпадение возвращает ложное значение (пустую строку), которое присваивается $a.

Затем ваш код запускает это:

if ($text=~ $a) {

И, поскольку $a - пустая строка, она совпадает (любая строка будет сопоставляться с пустой строкой, а Perl сообщает, что она соответствует $a (которая все еще содержит пустую строку).

Я не уверен, что вы пытались сделать с этой строкой:

my $a = m/\bhidden\b/;

Возможно, вы пытались каким-то образом "предварительно скомпилировать" регулярное выражение. В этом случае вы искали qr/.../, а не m/.../.

Так что, может быть, вы хотели это:

#!/usr/bin/perl

use strict;
use warnings;
use feature 'say';

my $text = 'Try to find the hidden string here! Hidden or hidden';
my $a = qr/\bhidden\b/; # CHANGED THIS
say "\$a is [$a]";
say "\$a is ", (defined $a ? 'defined' : 'undefined');
if ($text =~ $a) {
   print "I found word: $a";
}
else {
   print "No match, sorry.\n";
}

Что дает этот вывод:

$a is [(?^:\bhidden\b)]
$a is defined
I found word: (?^:\bhidden\b)

Или, если вы хотите показать то, что было сопоставлено, а не регулярное выражение, которое вы подходите, то вам нужно «захватить» этот текст:

#!/usr/bin/perl

use strict;
use warnings;
use feature 'say';

my $text = 'Try to find the hidden string here! Hidden or hidden';
my $a = qr/\b(hidden)\b/; # CHANGED THIS
say "\$a is [$a]";
say "\$a is ", (defined $a ? 'defined' : 'undefined');
if (my ($matched) = $text =~ $a) { # CHANGED THIS
   print "I found word: $matched"; # CHANGED THIS
}
else {
   print "No match, sorry.\n";
}

, что дает нам:

$a is [(?^:\b(hidden)\b)]
$a is defined
I found word: hidden

Ах, но вы хотите увидеть все слова, поэтому запишите совпадения в массив и используйте параметр /g, чтобы сопоставить несколько Несколько раз:

#!/usr/bin/perl

use strict;
use warnings;
use feature 'say';

my $text = 'Try to find the hidden string here! Hidden or hidden';
my $a = qr/\b(hidden)\b/;
say "\$a is [$a]";
say "\$a is ", (defined $a ? 'defined' : 'undefined');
if (my (@matched) = $text =~ /$a/g) { # CHANGED THIS
   print "I found word: @matched";    # CHANGED THIS
}
else {
   print "No match, sorry.\n";
}

Теперь мы получаем это:

$a is [(?^:\b(hidden)\b)]
$a is defined
I found word: hidden hidden

Это соответствует только двум экземплярам «скрытого», поскольку совпадение чувствительно к регистру. Так что отключите чувствительность к регистру с помощью /i.

#!/usr/bin/perl

use strict;
use warnings;
use feature 'say';

my $text = 'Try to find the hidden string here! Hidden or hidden';
my $a = qr/\b(hidden)\b/i; # CHANGED THIS
say "\$a is [$a]";
say "\$a is ", (defined $a ? 'defined' : 'undefined');
if (my (@matched) = $text =~ /$a/g) {
   print "I found word: @matched";
}
else {
   print "No match, sorry.\n";
}

, что дает нам:

$a is [(?^i:\b(hidden)\b)]
$a is defined
I found word: hidden Hidden hidden

Но, честно говоря, я думаю, предварительно скомпилировав регулярное выражение здесь просто усложняются вещи. Я написал бы этот код следующим образом (полностью удаляя переменную $a):

#!/usr/bin/perl

use strict;
use warnings;
use feature 'say';

my $text = 'Try to find the hidden string here! Hidden or hidden';

if (my (@matched) = $text =~ /\b(hidden)\b/gi) {
   print "I found word: @matched";
}
else {
   print "No match, sorry.\n";
}
1 голос
/ 02 марта 2020

Возможно, вы ищете этот кусок кода

use strict;
use warnings;
use feature 'say';

my $text='Try to find the hidden string here! Hidden or hidden';
my $re = qr/(hidden)/i;          # () capture found ignoring case

my @match = $text =~ /$re/g;     # g specifies to look for all accurances

say for @match;                  # output each element of @match

Вывод

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