【发布时间】:2019-09-06 19:33:48
【问题描述】:
我有一个字符串
XXXXYYYYZZZYYZZZYYYY 需要转换为
XXXXAAAYZZZAYZZZAAAY
$s =~ s/Y{2}+/AY/g;
这有 2 个问题,{2}+ 会得到 YYYY 到 AYAY;并且 AY 的长度与YYYY 不同(期望AAAY)
如何在 perl 中完成这项工作?
【问题讨论】:
我有一个字符串
XXXXYYYYZZZYYZZZYYYY 需要转换为
XXXXAAAYZZZAYZZZAAAY
$s =~ s/Y{2}+/AY/g;
这有 2 个问题,{2}+ 会得到 YYYY 到 AYAY;并且 AY 的长度与YYYY 不同(期望AAAY)
如何在 perl 中完成这项工作?
【问题讨论】:
使用“前瞻”:
$s =~ s/Y(?=Y+)/A/g;
(?=Y+) 表示“后跟一个或多个Y 字符”,因此任何Y 字符后跟另一个Y 字符都将替换为A。
【讨论】:
总是有不止一种方法可以做到这一点。我的建议是获取除最后一个之外的所有 Y,然后使用它创建一个相同长度的 As 字符串。 e 修饰符告诉 perl 在替换端执行代码而不是直接使用它,r 修饰符告诉 =~ 返回替换结果而不是直接修改输入文本(对这些有用-liner 测试等)。
$ perl -E 'say shift =~ s/(Y+)(?=Y)/"A"x length$1/gre' XXXXYYYYZZZYYZZZYYYY
XXXXAAAYZZZAYZZZAAAY
【讨论】:
(Y+)Y,而不是你可以用捕获组的长度替换为A 和一个额外的Y
$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+/&\n/g;s/Y/A/g;s/A\n/Y/g'
【讨论】: