Remova a funcionalidade da macro por meio de uma expressão regular

Remova a funcionalidade da macro por meio de uma expressão regular

Quero encontrar tudo \textbfno meu .texarquivo e excluí-lo, junto com seu argumento chaves {}. Por exemplo, quero mudar:

  1. \textbf{text}paratext

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

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

  4. \textbf{\textit{X{textbis}} text}para \textit{X{textbis}} text(onde Xestá uma quebra de parágrafo).

Tentei usar \\textbf\{([^}]*)\}in \1mas não funcionou porque para no início }.

Responder1

Como já mencionado por @David Carlisle você não pode igualar umarbitrário{ }número de pares bem aninhados . Mas, de uma perspectiva prática, você pode conhecer um limite superior para o nível máximo de aninhamento. Se este limite for conhecido, então é possível escrever uma expressão regular reconhecendo expressões bem entre parênteses até o nível máximo de aninhamento.

Para reconhecer \texbf{normal text}(ninho máximo = 1) você pode fazer

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

proibir {dentro dos colchetes é uma precaução para nunca combinar coisas com nível de aninhamento maior que o máximo.

Para combinar coisas com max nest = 2 você pode fazer o seguinte:

  1. primeiro você combina\\textbf\{
  2. então você combina qualquer caractere que não seja colchete com[^{}]*
  3. agora você pode ter terminado de combinar o conteúdo (o nível de aninhamento real é 1) e combinar o final com sucesso\}
  4. ou você pode estar em uma posição com um colchete aberto. Nesse caso, você precisa combinar algo com nível de aninhamento 0 e, em seguida, combinar o colchete fechado.

As etapas 2, 3 e 4 correspondem às [^{}]*(\{[^{}]*\}[^{}]*)?quais podem ser repetidas para que você possa combinar coisas como\textbf{bla\bla{bla}bla\bla{bla}bla}

Então, em suma, o nível máximo do ninho = 2 regex se parece com isso

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

Podemos extrapolar o esquema para ninho máximo = N maior que 2:

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

onde

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

Então, por exemplo, com max nest = 3 você obtém

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

o que é suficiente para capturar todos os casos mencionados na pergunta.

Responder2

se você puder usar quantificadores não gananciosos,

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

Ok, como Werner mencionou, isso só funciona com comandos não aninhados. Eu acho que não existe uma solução simples para isso e é um trabalho de analisador.

Se você quiser fazer isso de qualquer maneira com Regex, você pode substituir os não- \textbfcolchetes por um símbolo não usado e, no final, remover os \textbf-colchetes e alterar os símbolos de volta para colchetes:

1) Substitua todos os colchetes de fechamento \textbfpelo }Símbolo A,

2) Substitua todos os não \textbfcolchetes de abertura {pelo Símbolo B,

3) Substitua o restante \textbf{e }(de \textbf) por nada,

4) Substitua o Símbolo A por {e o Símbolo B por }


@Etapas 1 e 2:

Passo 1: }-> Smybol A, no meu exemplo alemão ö:

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

Substitua esta expressão por \1ö(não encontrei uma solução melhor para esta expressão)


Então faça o Passo 2: {-> Símbolo B, no meu exemplo alemãoä

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

Substitua esta expressão por ä.


Refaça essas etapas quantos níveis aninhados você tiver. Em seguida, siga as etapas restantes.


Bem, isso é mais uma macro regex e uma solução alternativa do que uma regex sólida, mas deve funcionar.

informação relacionada