我对“堆栈溢出”错误感到困惑 - “堆栈空间不足(应用程序错误代码:12246) - 当我执行”替换所有“时,我正在BBEdit中搜索
(@article(((?!eprint|@article|@book).)*\r)*)pmid = {(.+)}((((?!eprint|@article|@book).)*\r)*(@|\r*\z))
并替换为
\1eprinttype = {pubmed}, eprint = {\4}\5
我可以手动使用这些相同的模式,一次一个地查找&即使匹配不再发生,也可以毫无错误地更换。我也可以通过处理较小的文件来避免错误。
我怀疑这是我的低效和草率的正则表达式编码,应该责备,并希望专家帮助更有效地做到这一点。我正在尝试查找BibLaTeX参考书目中尚未包含eprint
字段但具有pmid
字段的所有条目,并将pmid
字段替换为相应的e - 打印规范(使用eprint
和eprinttype
)。
更新:经过一些实验,我发现a different approach是我唯一可以上班的地方。正在搜索
(?(?=@article(.+\r)+eprint = {(.+\r)+}\r*)(?!)|(@article(.+\r)+)pmid = {(.+)}((.+\r)+}\r*))
并替换为
\3eprinttype = {pubmed}, eprint = {\5}\6
诀窍。唯一的问题是反向引用是脆弱的,但我不能让named backreferences在BBEdit中工作。
答案 0 :(得分:3)
最后一部分可能导致catastrophic backtracking:
.)*\r)*(@|\r*\z))
如果你打破它并简化它,你基本上就会有一个.*
,一个\r*
和另一个\r*
。现在在输入结尾处描绘一串\r
个字符:每个\r
应如何分配?哪些小条款会吸收每个\r
字符?如果您有\r\r\r\r\r
,则可以使用\r
部分吃掉所有五个.*
,而使用\r*
部分则不会吃任何一个......或者,您可以弥补任何仍然匹配的排列数。由于*
是贪婪的,它会首先尝试填充.*
,但如果失败,它必须继续尝试排列直到其中一个有效。所以它可能会通过不必要的回溯来占用你的一大堆资源,直到它最终崩溃。
我不是正则表达式优化技术的专家,但如果我是你,我会从那里开始。
除非“NoRecurse”PCRE构建选项(aka 选择“--disable-stack-for-recursion”),必须有足够的堆栈空间 由调用应用程序或操作系统分配给PCRE。 ... 虽然PCRE的文档警告说“NoRecurse”构建选项使PCRE比替代方案慢,但使用它可以完全避免堆栈溢出问题。
所以我认为灾难性的回溯是一个不错的选择。我试着通过在更改PCRE上的构建选项之前调整你的正则表达式来解决它。
答案 1 :(得分:0)
显然这是一些错误。但你可以尝试稍微改变一下表达式。在不知道要求的情况下优化表达式很困难,但这是一个猜测:
(@article(?:(?:(?!eprint|@article|@book|pmid)[^\r])*+\r)*+)pmid = {([^\n\r]+)}((?:(?:(?!eprint|@article|@book)[^\r])*+\r)*(?:@|\r*\z))
替换为:
\1eprinttype = {pubmed}, eprint = {\2}\3
BBEdit似乎使用PCRE,除非它(非常)过时,上面的表达应该是兼容的。