Удаление нескольких последовательных слов, разделенных пробелом - PullRequest
0 голосов
/ 06 июля 2018

В приведенном ниже коде шаблон / man / совпадает дважды подряд. Поэтому, когда я подставляю этот шаблон, сопоставляется только первый случай, а второй - нет.

Как я понимаю, проблема с первым шаблоном совпадает до начала второго шаблона (то есть пробел после символа man является концом первого шаблона, а также началом первого шаблона). Таким образом, второй шаблон не соответствует. Как сопоставить этот шаблон глобально, когда он встречается последовательно.

use strict;
use warnings;

#my $name =" man sky man ";  #this works

my $name =" man man sky";    #this does'nt
$name =~s/ man / nam /g;    #expected= 'nam nam sky'
print $name,"\n";

Ответы [ 2 ]

0 голосов
/ 06 июля 2018

Как я понимаю, вы хотите заменить man между пробельными символами или началом / концом строки.

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

Используйте любой из двух:

$name =~ s/(?<=^|\s)man(?=\z|\s)/nam/g;
$name =~ s/(?<!\S)man(?!\S)/nam/g;

С точки зрения эффективности второй вариант лучше, так как чередование немного "дорого".

Положительный просмотр (?<=^|\s) соответствует местоположению в строке, которому предшествует начало строки (^) или (|), пробел (\s) и положительный просмотр (?=$|\s) гарантируют, что есть пробел или конец строки ($) сразу после man.

(?<!\S) отрицательный lookbehind соответствует расположению в строке, которому непосредственно не предшествует непробельный символ, т. Е. Если есть непробельный символ, совпадения не будет), и (?!\S) отрицательный прогноз указывает там сразу после man.

См. Более подробную информацию о Локальные утверждения в perlre.

0 голосов
/ 06 июля 2018

Регулярное выражение съедает символы, которым оно соответствует. Таким образом, чтобы избежать этого, вы должны использовать lookahead и lookbehind, чтобы соответствовать этому в этом случае. Чек perlre

$name =~ s/(?<=\s)man(?=\s)/nam/g;

Цитата из perlre

Взгляд вперед:

(?=pattern)
A zero-width positive lookahead assertion. For example, /\w+(?=\t)/ matches 
a word followed by a tab, without including the tab in $&.

Смотри сзади:

(?<=pattern) \K A zero-width positive lookbehind assertion. For
example, /(?<=\t)\w+/ matches a word that follows a tab, without
including the tab in $& . Works only for fixed-width lookbehind.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...