1

我的小宏的目标是找到第 1000 行,并在其中附加一个无意义的字符串,这样我就可以转置数据并在行值之间添加逗号。

我找到了替换功能的搜索词:((.+?\r\n){1000}) 并替换为:ZZZZZ

当我的行数少于 2500 时,一切正常。如果我超过了这个数字(它是近似值),我会收到一条错误消息:匹配表达式的复杂性超出了可用资源。谷歌给了我关于这个特定问题的 3 个结果,其中一个是关于 stackoverflow 的,但它似乎专注于一个非常不同的主题。主题:(unicode/multibyte 修饰符和 mb_ereg_replace 的不同结果

有人可以告诉我为什么我会收到此错误以及如何修复它,或者以不同的方式将“ZZZZZ”附加到我的数据集中的每 1000 行?

4

1 回答 1

1

标记/捕获组内的标记/捕获组会导致未定义的行为,这几乎总是不是预期的结果。

正确的 Perl 正则表达式搜索字符串应该是:^((?:.+?\r\n){1000})

?:由于开括号后,内部组现在是非标记组。内部组仅被定义为能够应用乘数表达式,因此不应标记某些内容,即在堆栈上复制找到的字符串以通过反向引用重复使用。

未来注意事项:像, , , ,一样
的乘数应用于标记组总是错误的。?+*{n}{n,}{n,m}

使用.*(除换行符以外的任何字符 0 次或多次)或.+ (除换行符以外的任何字符 1 次或多次)为 Perl 正则表达式引擎提供从哪里开始以及在哪里结束匹配字符的锚也很重要。匹配字符的结尾由 定义\r\n。但是您的搜索表达式中没有定义匹配字符的开头。^这就是我添加... 一行的开始的原因。我经常看到在搜索字符串中使用.*.+不指定匹配字符的开始和结束位置时出现意外的查找/替换结果。

此搜索表达式与回车和换行完全匹配 1000 行,并使用$1or\1可用于反向引用此块并在下一行插入字符串ZZZZZ

ZZZZZ应该在每 1000 行的末尾插入,而不是在下一行的开头。

出于这个原因,这个搜索表达式是必需的:^((?:.*?\r\n){999}.*)$

替换字符串是\1ZZZZZ$1ZZZZZ

在行首开始每次搜索的搜索字符串 -这里非常重要- 匹配 999 行,每行有 0 个或更多字符,第 1000 行有 0 个或更多字符贪婪,但不包括换行符回车和换行。$也适用于 Perl 正则表达式引擎的文件结尾。因此,这个 Perl 正则表达式搜索字符串也适用于例如正好有 5000 行的文件,而最后一行没有行终止。

为什么在^这里获得正确的结果非常重要?

在每第 1000 行的末尾插入后ZZZZZ,当前位置在第 1000 行的末尾,紧接在该行的回车和换行之前。如果没有^搜索,则将从当前第 1000 行的匹配\r\n.*... 0或更多)开始,而不是从下面下一行的开头。

于 2016-05-07T21:12:26.740 回答