Множественное вхождение строки в строку, которая должна быть обработана

#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
  

Некоторые другие примечания, которые могут оказаться полезными:

Ответ №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 помощью , но оно того стоит.