将带反斜杠和大括号的字符串嵌入更多大括号中的正则表达式

Regular expression to embed string with backslash and curly braces in more curly braces

这是一个 cross-post from TeX,但它没有在那里得到任何答案。而且由于我认为这个问题更多地与我对正则表达式的理解(或者更好,缺乏)有关,而不是与 LaTeX 本身有关,所以 Whosebug 可能是更好的起点。

我想使用 BibTool(它是用 C 语言编写的,如果这对这里有任何影响的话)将一些字符串括在 bib 文件中的花括号中。测试 bib 条目如下所示:

@Article{Cite1,
author       = {Adelbert, A.},
date         = {2020},
journaltitle = {A Journal},
title        = {A title with just \textit{Test} structure and some chemistry \ce{CO2}},
number       = {2},
pages        = {1--4},
volume       = {1},
}

我创建了以下 BibTool 资源文件:

resource {biblatex}
preserve.keys = on
preserve.key.case = on
rewrite.rule = {"\\(.*{.*}\)" "{{}}"}

rewrite.rule 应该是:

  1. 查找任何字段中以 \ 开头的所有字符串,例如 \ce{}\textit{} 等。这是由 \ 开头的字符串完成的正则表达式。
  2. 当找到这个字符串时,将以下字符串保存在一个组中,用\(\)表示:一个随机字符串开头,后面是{,一个随机字符串,后面是};即字符串 textit{Test}.
  3. 将此字符串写回相同位置,但将其括在 double-set 花括号 "{{}}".

目前管理的内容:

  1. 它显然找到了所有以 \ 开头的命令。
  2. 它保存字符串并将它们写回到文件中。

至此,代码returns如下

@Article{Cite1,
Author       = {Adelbert, A.},
Date         = {2020},
JournalTitle = {A Journal},
Title        = {A title with just {{textit{Test} structure and some chemistry {{ce{CO2}}}}}},
Number       = {2},
Pages        = {1--4},
Volume       = {1},
}

你看它找到字符串并在每个字符串的开头放置 {{。不幸的是,它将 }} 放在字段的末尾, 而不是 字符串,所以我现在在标题字段的末尾有 6 个大括号。大括号确实匹配,其中只有两个应该在 {{textit{Test} 之后而不是最后。我尝试了各种结构,例如 rewrite.rule = {"\\(.*{.*}\)$" "{{}}"}rewrite.rule = {"\\(.*{.*}\) ?$" "{{}}"}rewrite.rule = {"\\(.*{.*}\)*$" "{{}}"},但这都不起作用。

当试图在字符串的开头取回 \ 时,使用 rewrite.rule = {"\\(.*{.*}\)" "{{\}}"} 我取回了 \,但还有数千个 {} 直到我收到 Rewrite limit exceeded 错误。

我不太擅长正则表达式,很高兴收到任何评论。

默认情况下.*的行为是匹配尽可能多的字符。这在正则表达式中称为 'greedy matching'。

您的模式很可能在命中第一个 \ 时与以下内容匹配:

\textit{Test} structure and some chemistry \ce{CO2}}

将文本替换为:

{{textit{Test} structure and some chemistry \ce{CO2}}}}

然后找到下一个\并替换为:

\ce{CO2}}}} becomes {{ce{CO2}}}}}}

总效果:

{A title with just \textit{Test} structure and some chemistry \ce{CO2}}

{A title with just {{textit{Test} structure and some chemistry {{ce{CO2}}}}}}

要更改大多数正则表达式风格的行为,您可以在量词后放置 ?.*? 使其成为 'lazy',即匹配最少数量的字符。

我的方法将使用两个阶段。在第一阶段,我将使用一个参数处理宏,并在结果中用替换表示替换 \(此处为 ##)。在第二个 pahe 中,我只是将 ## 替换为 \.

在 BibTool 中看起来如下:

rewrite.rule {"\\(\([a-zA-Z]+\|.\){[^{}]*}\)" "{##}"}
rewrite.rule {"##" "\"} 

请注意,通常描述的任务不能用正则表达式解决...