透過正規表示式刪除巨集的功能

透過正規表示式刪除巨集的功能

我想找到\textbf我的文件中的所有內容.tex並將其連同它的參數大括號一起刪除{}。例如我想改變:

  1. \textbf{text}text

  2. \textbf{text \textit{textbis}}text \textit{textbis}

  3. \textbf{\textit{\textls[-5]{textbis}} text}\textit{\textls[-5]{textbis}} text

  4. \textbf{\textit{X{textbis}} text}\textit{X{textbis}} text(哪裡X是段落分隔符號)。

我嘗試使用\\textbf\{([^}]*)\}in\1但它不起作用,因為它一開始就停止了}

答案1

正如@David Carlisle 已經提到的,你無法匹配隨意的嵌套良好的{ }對的數量。但是,從實際角度來看,您可能知道最大嵌套等級的上限。如果這個界限是已知的,那麼就可以寫一個正規表示式來識別最大嵌套層級的括號表達式。

要辨識\texbf{normal text}(最大嵌套= 1),你可以這樣做

\textbf{([^{}]*)}

禁止{在括號內是一種預防措施,以防止匹配巢狀層級大於最大層級的事物。

要符合 max Nest = 2 的內容,您可以執行以下操作:

  1. 首先你匹配\\textbf\{
  2. 然後將任何非括號字元與[^{}]*
  3. 現在你可能已經完成了內容的匹配(實際嵌套級別為1)並愉快地匹配了結局\}
  4. 或者,您可能處於帶有開括號的位置。在這種情況下,您需要匹配嵌套層級為 0 的內容,然後匹配閉括號。

步驟 2、3 和 4 對應於[^{}]*(\{[^{}]*\}[^{}]*)?可以重複的步驟,以便您可以匹配諸如\textbf{bla\bla{bla}bla\bla{bla}bla}

所以總而言之,最大嵌套層級 = 2 正規表示式看起來像這樣

\\textbf\{(([^{}]*(\{[^{}]*\}[^{}]*)?)*)\}

我們可以推論 max Nest = N 大於 2 的方案:

\\textbf\{(([^{}]*(\{RN\}[^{}]*)?)*)\}

在哪裡

R1 = [^{}]*
RN = ([^{}]*(\{R(N-1)\}[^{}]*)?)*

因此,例如 max Nest = 3 你會得到

\\textbf\{(([^{}]*(\{(([^{}]*(\{[^{}]*\}[^{}]*)?)*)\}[^{}]*)?)*)\}

這足以捕捉您在問題中提到的所有情況。

答案2

如果你可以使用非貪婪量詞,

\\textbf\{(.*?)\}\1

好的,正如維爾納所提到的,這僅適用於非嵌套命令。我認為,對此沒有簡單的解決方案,這是解析器的工作。

如果您想使用正規表示式執行此操作,可以將非 - 括號替換\textbf為未使用的符號,然後最後刪除\textbf- 括號並將符號變更回括號:

1) 將所有右括號替換\textbf}符號 A,

2) 將所有左括號替換\textbf{符號 B,

3) 將剩餘的\textbf{}(來自\textbf) 替換為空,

4) 將符號 A 替換為@Step 1 和 2 {,符號 B 替換為}


@Step 1 和 2:

第 1 步:}-> Smybol A,在我的範例中是德語ö

(?<=(?<!\\textbf)\{(?!.*?\{)).*?\}

將此表達式替換為\1ö(我沒有找到該表達式的更好解決方案)


然後執行步驟 2:{-> 符號 B,在我的範例中為德語ä

(?<!\\textbf)\{(?!.*?\{)

將此表達式替換為ä.


重做這些步驟,巢狀的層數與您的巢狀層數一樣多。然後執行其餘步驟。


好吧,這更像是一個正規表示式巨集和一種解決方法,而不是一個可靠的正規表示式,但它應該可以工作。

相關內容