Удалить функциональность макроса с помощью регулярного выражения

Удалить функциональность макроса с помощью регулярного выражения

Я хочу найти все \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\{([^}]*)\}, \1но ничего не вышло, потому что сначала он останавливается }.

решение1

Как уже сказал @David Carlisle, вы не можете сопоставитьпроизвольныйколичество хорошо вложенных { }пар. Но с практической точки зрения вы можете знать верхнюю границу максимального уровня вложенности. Если эта граница известна, то можно написать регулярное выражение, распознающее хорошо заключенные в скобки выражения вплоть до максимального уровня вложенности.

Чтобы распознать \texbf{normal text}(максимальное гнездо = ​​1), вы можете сделать

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

Запрет {внутри скобок — это мера предосторожности, чтобы никогда не сопоставлять элементы с уровнем вложенности, превышающим ваш максимальный уровень.

Чтобы сопоставить элементы с максимальным гнездом = 2, можно сделать следующее:

  1. сначала вы сопоставляете\\textbf\{
  2. затем вы сопоставляете любой символ, не являющийся скобкой, с[^{}]*
  3. теперь вы, возможно, закончили сопоставление содержимого (фактический уровень вложенности равен 1) и успешно сопоставляете окончание\}
  4. или вы можете оказаться в позиции с открытой скобкой. В этом случае вам нужно сопоставить что-то с уровнем вложенности 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

Хорошо, как сказал Вернер, это работает только с невложенными командами. Я думаю, что для этого нет простого решения, и это работа парсера.

Если вы все равно хотите сделать это с помощью Regex, вы можете заменить неиспользуемые \textbfскобки на неиспользуемый символ, а затем в конце удалить \textbfскобки и заменить символы обратно на скобки:

1) Заменить все закрывающие \textbfскобки без знаков }на символ A,

2) Заменить все открывающиеся \textbfскобки без знаков {на символ B,

3) Заменить оставшиеся \textbf{и }(из \textbf) ничем,

4) Замените символ A на , {а символ B на }


@Step 1 и 2:

Шаг 1: }-> Smybol A, в моем примере на немецком языке ö:

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

Замените это выражение на \1ö(лучшего решения для этого выражения я не нашел)


Затем выполните Шаг 2: {-> Символ B, в моем примере немецкийä

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

Замените это выражение на ä.


Повторите эти шаги, сколько у вас вложенных уровней. Затем выполните оставшиеся шаги.


Ну, это скорее макрос регулярного выражения и обходной путь, чем полноценное регулярное выражение, но оно должно работать.

Связанный контент