Как заменить последовательные и идентичные символы в Perl?

#regex #string #perl #replace

#регулярное выражение #строка #perl #заменить

Вопрос:

У меня есть строка, XXXXYYYYZZZYYZZZYYYY которая должна быть преобразована в XXXXAAAYZZZAYZZZAAAY

$s =~ s/Y{2} /AY/g;

это имеет 2 проблемы, {2} приведет к YYYY к AYAY; и AY не такой длины, как YYYY (ожидаемый AAAY )

Как это сделать в perl?

Ответ №1:

Используйте «взгляд вперед»:

 $s =~ s/Y(?=Y )/A/g;
 

(?=Y ) означает «за которым следует один или несколько Y символов», поэтому любой Y символ, за которым следует другой Y символ, будет заменен на A .

Больше информации от perlretut

Ответ №2:

Всегда есть более одного способа сделать это. Мое предложение состоит в том, чтобы захватить все Ys, кроме последнего, а затем использовать это для создания строки As той же длины. e Модификатор сообщает perl выполнить код на стороне замены, а не использовать его напрямую, и r модификатор сообщает =~ вернуть результат замены вместо прямого изменения входного текста (полезно для этих однострочных тестов, среди прочего). места).

 $ perl -E 'say shift =~ s/(Y )(?=Y)/"A"x length$1/gre' XXXXYYYYZZZYYZZZYYYY
XXXXAAAYZZZAYZZZAAAY
 

Комментарии:

1. На самом деле это не одно и то же — вы переместили за пределы захвата, поэтому длина всегда равна 1, и при замене будет опущено окончание Y(s), а это означает, что сопоставляется и, следовательно, заменяется больше текста. Да, это можно заставить работать без предварительного просмотра, но я бы предпочел, чтобы это было.

2. мой плохой, да (Y )Y , чем вы можете заменить длину захваченной группы как A и одну дополнительную Y

3. Регулярные выражения: обычно не работают с первой попытки. 🙂 Вот почему мне пришлось попробовать три раза, чтобы заставить ответ, приведенный выше, работать 🙂

Ответ №3:

$s =~ s/Y{2} /AY/g
Шаблон RHS является неоднозначно неясным шаблоном: Y{2} это очень редко используемый шаблон регулярных выражений, за исключением случаев {} , когда он очень редко доступен в нескольких продвинутых движках регулярных выражений, включая perl, возможно, в качестве функции регулярных выражений, называемой «атомарная группировка».
Возможно, вы имели в виду (Y{2}) which is (YY) или Y{2,} что YY
в perl это не сложно, просто и легко, поскольку он поддерживает lookaround функцию

 perl -e '$s=XXXXYYYYZZZYYZZZYYYY ;$s =~ s/Y(?=Y)/A/g;print $s'
 

на самом деле более низкий движок регулярных выражений, такой sed, все еще может это сделать, хотя и громоздким, непростым способом

 echo XXXXYYYYZZZYYZZZYYYY |sed -E 's/YY /amp;n/g;s/Y/A/g;s/An/Y/g'