Aplicar a substituição de item dentro de enumerar em regex Perl?

2

Dados

7. Masi is the same as
\begin{enumerate}
A
B
ABC ha lorem
\end{enumerate}

1. ABC is
\begin{enumerate}
P
B
Lorem maam
\end{enumerate}

que eu quero ser

7. Masi is the same as
\begin{enumerate}
\item A
\item B
\item ABC ha lorem
\end{enumerate}

1. ABC is
\begin{enumerate}
\item P
\item B
\item Lorem maam
\end{enumerate}

Meu regex de inicialização é baseado nesta resposta

perl -000pe
s/\n/\n\begin{enumerate}\n [A-Za-z1-9]* \end{enumerate}/
... [problem here!]
masi.tex

onde

  • -000: ativa o modo de parágrafo do Perl, isso faz com que "linhas" sejam definidas por duas novas linhas consecutivas (\ n \ n), de modo que cada uma das suas perguntas seja tratada como uma única linha.
  • -pe: leia cada linha do arquivo de entrada e imprima-o (-p) após aplicar o script passado como -e.

Eu quero substituir o início de cada nova linha na partida por \item . Meu pseudocódigo para problema aqui código

s/\n/\item /g

para aplicar coisas dentro do ambiente de enumeração.

Como

    
por Léo Léopold Hertz 준영 05.06.2014 / 14:06

3 respostas

4

Você pode usar o operador .. ou intervalo para limitar as substituições às seções de início / fim :

while (<DATA>) {
   if ( /\begin/ .. /\end/ ) {
       s/^(?!\)/\item /;  
   }
   print;
}

__DATA__
7. Masi is the same as
\begin{enumerate}
A
B
ABC ha lorem
\end{enumerate}

1. ABC is
\begin{enumerate}
P
B
Lorem maam
\end{enumerat

Se você preferir um script de linha de comando:

perl -ne 'if (/\begin/../\end/) {s/^(?!\)/\item /};print'

Ou mais curto com um print implícito:

perl -pe 'if (/\begin/../\end/) {s/^(?!\)/\item /}'

O (?!...) é uma afirmação negativa de antecipação.

    
por 05.06.2014 / 14:35
3

Outra Perl solution:

$ perl -pe '
    if (/\begin/../\end/) {
        next if /\begin/ || /\end/;
        s/^/\item /;
    }
' file
7. Masi is the same as
\begin{enumerate}
\item A
\item B
\item ABC ha lorem
\end{enumerate}

1. ABC is
\begin{enumerate}
\item P
\item B
\item Lorem maam
\end{enumerate}

Explicação

  • if (/\begin/../\end/) : nosso delimitador de linhas começa com \begin e termina com \end .
  • next if /\begin/ || /\end/ : não precisamos de início e fim, pule-os.
  • s/^/\item / : substituímos o início de cada linha pelo padrão desejado.
  • A opção -p faz com que perl imprima cada linha depois que a processamos.
por 05.06.2014 / 14:57
2

Use um sinalizador. Defina como 1 ao digitar enumerar, limpe-o no final. Inserir item quando o sinalizador estiver definido:

perl -pe '$inside = 0 if /\end{enumerate}/;
          print "\item " if $inside;
          $inside = 1 if /\begin{enumerate}/;
         ' input.tex

Note que eu verifico o final antes de imprimir, então o \item não é prefixado na linha final.

    
por 05.06.2014 / 14:18