如何在Perl中替换连续且相同的字符?

时间:2019-04-16 16:16:30

标签: regex string perl replace

我有一个像 XXXXYYYYZZZYYZZZYYYY,需要将其转换为 XXXXAAAYZZZAYZZZAAAY

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

这有2个问题,{2}+将YYYY转到AYAY;并且AY与YYYY的长度不同(期望AAAY

如何在perl中完成此操作?

3 个答案:

答案 0 :(得分:6)

使用“向前看”:

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

(?=Y+)的意思是“后跟一个或多个Y字符”,因此任何Y字符后跟另一个Y字符将被替换为{{1 }}。

More info from perlretut

答案 1 :(得分:4)

总是有不止一种方法来做到这一点。我的建议是获取除最后一个Y外的所有Y,然后使用它创建长度相同的As字符串。 e修饰符告诉perl在替换端执行代码,而不是直接使用它,而r修饰符告诉=~返回替换的结果,而不是修改输入文本直接(对于这些单线测试以及其他地方很有用)。

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

答案 2 :(得分:0)

$s =~ s/Y{2}+/AY/g
RHS Pattern is ambiguously obscure pattern: Y{2}+, that's very rarely used regex pattern except if {}+ very rarely is available in few advanced regex engine, including perl maybe, as a regex feature called 'atomic grouping'.
You might have meant (Y{2})+ which is (YY)+ or Y{2,} which is YY+
in perl it's no brainer simple and easy as it supports lookaround feature

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

actually lower regex engine such sed still can do it albeit in cumbersome, uneasy way

echo XXXXYYYYZZZYYZZZYYYY |sed -E 's/YY+/&\n/g;s/Y/A/g;s/A\n/Y/g'