我想\textbf
在我的.tex
文件中查找所有内容并将其连同其参数括号一起删除{}
。例如,我想更改:
\textbf{text}
到text
\textbf{text \textit{textbis}}
到text \textit{textbis}
\textbf{\textit{\textls[-5]{textbis}} text}
到\textit{\textls[-5]{textbis}} text
\textbf{\textit{X{textbis}} text}
至\textit{X{textbis}} text
(X
段落分隔符的位置)。
我尝试使用\\textbf\{([^}]*)\}
,\1
但是没有用,因为它一开始就停止了}
。
答案1
正如 @David Carlisle 所提到的,你无法匹配随意的嵌套良好的{
}
括号对的数量。但是,从实际角度来看,您可能知道最大嵌套级别的上限。如果知道这个上限,那么就可以编写一个正则表达式来识别嵌套级别最高的括号表达式。
要识别\texbf{normal text}
(最大嵌套= 1),您可以这样做
\textbf{([^{}]*)}
{
括号内的禁止是一种预防措施,永远不会匹配嵌套级别大于最大值的内容。
要匹配最大嵌套数 = 2 的事物,您可以执行以下操作:
- 首先你匹配
\\textbf\{
- 然后你匹配任何非括号字符
[^{}]*
- 现在你可能已经匹配完了内容(实际嵌套层数为1),开心地匹配结尾
\}
- 或者,您可能处于一个带有左括号的位置。在这种情况下,您需要匹配嵌套级别为 0 的内容,然后匹配右括号。
步骤 2、3 和 4 对应于[^{}]*(\{[^{}]*\}[^{}]*)?
可以重复的内容,因此您可以匹配以下内容\textbf{bla\bla{bla}bla\bla{bla}bla}
因此,总而言之,最大嵌套级别 = 2 正则表达式如下所示
\\textbf\{(([^{}]*(\{[^{}]*\}[^{}]*)?)*)\}
我们可以推断出最大嵌套 = N 大于 2 的方案:
\\textbf\{(([^{}]*(\{RN\}[^{}]*)?)*)\}
在哪里
R1 = [^{}]*
RN = ([^{}]*(\{R(N-1)\}[^{}]*)?)*
例如,当最大嵌套数 = 3 时,您将获得
\\textbf\{(([^{}]*(\{(([^{}]*(\{[^{}]*\}[^{}]*)?)*)\}[^{}]*)?)*)\}
这足以涵盖你在问题中提到的所有情况。
答案2
如果你可以使用非贪婪量词,
\\textbf\{(.*?)\}
用。。。来代替\1
好的,正如 Werner 提到的,这只适用于非嵌套命令。我认为,这没有简单的解决方案,这是一个解析器的工作。
如果您仍想使用 Regex 执行此操作,则可以用\textbf
未使用的符号替换非括号,然后最后删除括号\textbf
并将符号改回括号:
1)将所有非右括号替换\textbf
为}
符号 A,
2) 将所有左非括号替换\textbf
为{
符号 B,
3)将剩下的\textbf{
和}
(从\textbf
)替换为空,
4)用 步骤 1 和 2替换符号 A{
和符号 B :}
步骤 1:}
-> Smybol A,在我的示例中为德语ö
:
(?<=(?<!\\textbf)\{(?!.*?\{)).*?\}
用\1ö
(我没有找到更好的解决方案) 替换这个表达式
,然后执行步骤 2:{
-> 符号 B,在我的例子中是德语ä
(?<!\\textbf)\{(?!.*?\{)
将此表达式替换为ä
。
重复这些步骤,直到嵌套层数达到要求的水平。然后执行剩余步骤。
嗯,这更像是一个正则表达式宏和一种解决方法,而不是一个可靠的正则表达式,但它应该可以工作。