#perl
#perl
Вопрос:
У меня есть два вопроса.
1: если у меня есть строка, подобная этой «Фрукты: манго-банан», я хочу захватить часть «Манго-банан» и присвоить ее другой переменной. В настоящее время я следую этому,
if(/$line == Fruits:s(w )/){
myFav=$1;
}
но он возвращает только «Манго», а не «Манго-банан». Кто-нибудь может подсказать, как получить полный список фруктов, разделенный пробелом.
2. Если у меня есть какая-то строка, повторяющаяся в той же строке, я хочу зафиксировать все вхождения.
Например: если у меня есть строка типа «У меня есть фрукты: манго, а цвет фруктов: банан зеленый». Я также хочу захватить значения Mango и Banana.
if(/$line == Fruit:s(w )/){
myFav=$1;
}
Обычно приведенный выше код прекращает поиск после первого появления «Fruit:». Кто-нибудь может помочь с двумя вышеупомянутыми?
Заранее спасибо 🙂
Комментарии:
1. Два вопроса лучше решать в виде двух сообщений.
Ответ №1:
Одним из решений было бы полагаться на тот факт, что ваши названия фруктов написаны с большой буквы.
Тем не менее, у меня возникнет соблазн использовать два регулярных выражения, одно для фруктов и одно для фруктов.
use strict;
use warnings;
while (<DATA>) {
chomp;
while (/Fruits?: ((?:[A-Z]w*s*) )(?<!s)/g) {
print "Line $. - '$1'n";
}
}
__DATA__
Fruits: Mango Banana
I have Fruit: Mango and the color of the Fruit: Banana is green
Выводит:
Line 1 - 'Mango Banana'
Line 2 - 'Mango'
Line 2 - 'Banana'
Ответ №2:
Используйте это вместо: ([ws] )
if($line =~ /Fruits:s([ws] )/) {
$myFav = $1;
}
И всегда:
use strict;
use warnings;
Ответ №3:
$line="I have Fruit: Mango and the color of the Fruit: Banana is green";
@found=($line=~m/Fruit: w /g); # Make sure to use g operator, finds all matches in $line
for each $s (@found)
{print "$sn";
}
Ответ №4:
1/ Причина, по которой регулярное выражение возвращает только «Манго», заключается в том, что w соответствует символам «word». Это цифры, буквы и подчеркивание (то есть символы, допустимые в именах символов Perl). Если вы хотите сопоставить пробел между двумя названиями фруктов, вам нужно добавить пробел (или, возможно, лучше, s, который соответствует всем пробелам) в ваше регулярное выражение. Вероятно, вы хотите поместить оба этих атома в класс символов.
/Fruit:s([ws] )/
2/ По умолчанию оператор сопоставления соответствует только первому вхождению регулярного выражения во входной строке. Чтобы сопоставить их все, вам нужно добавить /g
опцию к оператору сопоставления.
/Fruit:s([ws] )/g
Некоторые другие примечания, которые могут оказаться полезными:
- Учебное пособие по регулярным выражениям Perl — хороший способ изучить этот материал
- Документация по регулярным выражениям Perl содержит все подробности.
- Документация по оператору Perl объясняет оператор сопоставления.
- Добавление
use strict
иuse warnings
ко всему вашему коду — хорошая привычка. -
Вы снова сопоставляете строку с регулярным выражением, используя оператор привязки (
=~
), а не оператор присваивания (=
). И входная строка, и оператор привязки выходят за пределы оператора сопоставления.если($line =~ /Fruits:s(w )/){
Ответ №5:
В вашем первом сообщении вы используете:
if ( /$line == Fruits:s(w )/ ) {
Во-первых, вы должны использовать ~=
вместо ==
для регулярных выражений. Во-вторых, вы помещаете косые черты вокруг регулярных выражений следующим образом:
if ( $line ~= /Fruits:s(w )/ ) {
Теперь это w
слово, которое включает буквы, цифры, символы подчеркивания и все. Он не соответствует пробелам.
У вас есть:
Fruits: Mango Banana
Итак, w
будет соответствовать Mango
, но перестанет соответствовать пробелу после Mango
.
Если вы хотите сопоставить оба:
if ( $line =~ /^Fruits:s (. )/ ) {
Обратите .
внимание, что будет соответствовать любому символу, включая пробел. Знак plug означает совпадение хотя бы с одним пробелом. Звездочка соответствует нулю или более. Обратите внимание, что я также использую s
вместо just s
. Таким образом, если после будет более одного пробела Fruits
, у вас будет совпадение.
Во втором примере вы можете сделать это:
my @fruits = $line =~ /Fruits:s (S )/g
В g
конце допускается несколько совпадений. В противном случае будет использоваться только первая строка. S
Представляет все непростое пространство, в которое будут включены возможные тире. Это поместит ваши совпадения в массив @fruits
. Прочитайте руководство по регулярным выражениям. Это поможет вам немного лучше понять, что происходит.
Всегда используйте use strict;
и use warnings;
в вашей программе. Это поможет вам отлавливать ошибки. Вам придется объявлять переменные с my
помощью , но оно того стоит.