我正在尝试匹配文本文件中的连续相似行,并且仅保留最后一行。每行包含一个数字计数,所以我要匹配文本和数字以获取计数。
例如,如果我有很多连续的字符为'a'的行,则可以按以下方式进行操作。
$ (for i in `seq 1 1 100000`; do echo a; done;) |
perl -0777 -pe 's/(a\n)*(a\n)/\2/igs'
a
但是,如果我将它与数字的其他匹配项一起使用,则perl似乎会以2 ^ 15的批次进行处理。
$ (for i in `seq 1 1 100000`; do echo $i; done;) |
perl -0777 -pe 's/(\d*\n)*(\d*\n)/\2/igs'
32768
65536
98304
100000
我做错什么了吗,这是perl中的bug,还是记录在某处?最好的方法是什么?
我正在使用perl 5.22.1。
答案 0 :(得分:1)
如果将警告编译指示添加到perl脚本中,则会获得以下信息:
Complex regular subexpression recursion limit (32766) exceeded at -e line 1, <> chunk 1.
根据perldiag:
超出了常规规则子表达式递归限制(%d)(W regexp)
在复杂情况下,正则表达式引擎使用递归 需要回溯的地方。递归深度限制为32766, 或在堆栈无法增长的架构中更少 任意地。 (“简单”和“中等”情况在没有 递归并且不受限制。)尝试缩短字符串 正在检查中;在Perl代码中循环(例如with while)而不是 在正则表达式引擎中;或重写正则表达式 以便更简单或减少回溯。 (有关详情,请参见perlfaq2 有关掌握正则表达式的信息。)
以下是您可以使用的解决方案:
perl -ne'
if (/^\d+\n) { $buf = $_; next; }
print(substr($buf, 0, -1, ""), $_);
END { print($buf) }
'