• Publicidad

Acotar expresión regular

¿Apenas comienzas con Perl? En este foro podrás encontrar y hacer preguntas básicas de Perl con respuestas aptas a tu nivel.

Acotar expresión regular

Notapor pablgonz » 2013-11-15 23:22 @015

Hola, amigos del foro, estoy trabajando en un pequeño script... y tengo algunas dudas con las expresiones regulares que estoy usando. Va así:

Tengo ficheros de entrada de las siguiente formas (LaTeX)
Sintáxis: [ Descargar ] [ Ocultar ]
Using latex Syntax Highlighting
  1. \documentclass{article}
  2. \usepackage{pstricks-add}
  3. \newenvironment{postscript}{}{}
  4. \begin{document}
  5. Los entornos pstricks se inician \verb|\pspicture(argumento) o \pspicture*(argumento)| para plain TeX
  6. y \verb+\begin{pspicture} o \begin{pspicture*}+ para LaTeX, antes o después de cada entorno, es necesario
  7. definir \verb'\psset{opciones}' por ejemplo:
  8. \verb+\psset{opciones}\begin{pspicture}+ o \verb-\begin{pspicture}\psset{opciones}- y para cerrar los entornos usamos
  9. (dependiendo) \verb*'\endpspicture' para plain TeX y \verb*#\end{pspicture} o \end{pspicture*}# para LaTeX.
  10. Algunas ocasiones es necesario definir un nuevo entorno para incluir nuestras definiciones dentro de el, por
  11. ejemplo \verb<\newenvironment{postscript}{}{}< e incluir nuestros entornos dentro de el, es decir, las lineas deben ser
  12. \verb|\begin{postscript} \psset{opciones} \begin{pspicture}| o \verb|\begin{postscript} \begin{pspicture} \psset{opciones}|
  13. pero no \verb|\psset{opciones}\begin{postscript}\begin{pspicture}| o \verb|\psset{opciones}\begin{pspicture}\begin{postscript}|
  14. y para cerrar el entorno usamos \verb&\end{postscript}&. Para comentar una linea puedes usar \verb|%| antes de cada linea
  15. por ejemplo \verb|% \pspicture*(argumento) o %\pspicture*(argumento) o %%%%\pspicture*(argumento)|. Veamos algunos ejemplos:
  16.  
  17. %\begin{postscript}
  18. \begin{postscript}
  19. \psset{unit=1.0cm}
  20. \begin{pspicture}[showgrid=true](4,2)
  21.   \psscaleboxto(8,2){foo bar baz}
  22. \end{pspicture}
  23. \end{postscript}
  24.  
  25. \begin{pspicture*}(4,2)(8,1)
  26. \psset{unit=1.0cm}
  27. \psscaleboxto(8,2){foo bar baz}
  28. \end{pspicture*}
  29.  
  30. %%% \pspicture*(4,2)(8,1) o \begin{pspicture*}(4,2)(8,1)
  31. \pspicture*(4,2)(8,1)
  32. \psset{unit=1.0cm}
  33. \psscaleboxto(8,2){foo bar baz}
  34. \endpspicture
  35. % se puede \endpspicture o \end{pspicture*}
  36. % \pspicture(4,2)(8,1) o \begin{pspicture}(4,2)(8,1)
  37. \pspicture(4,2)(8,1)
  38. \psset{unit=1.0cm}
  39. \psscaleboxto(8,2){foo bar baz}
  40. \endpspicture
  41. %\endpspicture o \end{pspicture}
  42. \end{document}
  43.  
Coloreado en 0.003 segundos, usando GeSHi 1.0.8.4

Quiero los siguientes cambios, cuando este dentro de \verb, verb* o despues de %
Sintáxis: [ Descargar ] [ Ocultar ]
  1. pspicture por TRICKS 
  2. pspicture* por TRICKS* 
  3. postscript por POSTRICKS 
  4. endpspicture por ENDTRICKS 

Pero, que no modifique, las lineas que están fuera de \verb,verb* o % en el documento, específicamente, que no cambie:
Sintáxis: [ Descargar ] [ Ocultar ]
  1. \pspicture(algo) o \endpspicture 
  2. \pspicture*(algo) o \endpspicture 
  3. \begin{pspicture} o \end{pspicture} 
  4. \begin{pspicture*} o \end{pspicture*} 
  5. \begin{postscript} o \end{postscript} 

El script que utilizo es el siguiente:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl -w
  2. use v5.16;
  3. use autodie;
  4. use strict;
  5.  
  6. my $entrada = $ARGV[0];                # el fichero como primer argumento
  7. my $salida  = 'salida.tex';            # fichero de salida
  8.  
  9. open( AE, '<', $entrada );             # leemos el archivo Entrada
  10. undef $/;                              # modo 'slurp'
  11. my ( $uno, $dos ) = split( /\\begin\{document\}/, <AE>, 2 );
  12. close AE;
  13.  
  14. my @coment = split /\n/, $dos;
  15. my @preamb;
  16.  
  17. foreach my $line (@coment) {           # modificamos las líneas
  18.     chomp($line);
  19.  
  20.     # Apertura de entornos ps
  21.     # Cambiamos \pspicture,\pspicture*,\begin{pspicture},\begin{postscript} por TRICKS y POSTRICKS
  22.     $line =~ s/(\\[V|v]erb[\*]?[[:punct:]]{1}.+?)\\pspicture/$1\\TRICKS/g;                          # cambiamos \pstricks[*] por \TRICKS[*]
  23.     $line =~ s/(\\[V|v]erb[\*]?[[:punct:]]{1}.+?)\\begin\{pspicture/$1\\begin\{TRICKS/g;            # cambiamos
  24.     $line =~ s/(\\[V|v]erb[\*]?[[:punct:]]{1}.+?)\\begin\{postscript\}/$1\\begin\{POSTRICKS\}/g;    # cambiamos
  25.  
  26.     # Cambiamos los comentarios en TeX cuando comienzen con %
  27.     $line =~ s/(\%.+?)\\pspicture/$1\\TRICKS/g;                        # cambiamos
  28.     $line =~ s/(\%.+?)\\begin\{pspicture/$1\\begin\{TRICKS/g;          # cambiamos
  29.     $line =~ s/(\%.+?)\\begin\{postscript\}/$1\\begin\{POSTRICKS\}/g;  # cambiamos
  30.  
  31.     # Cierre entornos pspicture
  32.     $line =~ s/(\\[V|v]erb[\*]?[[:punct:]]{1}.+?)\\endpspicture/$1\\ENDTRICKS/g;               # cambiamos \pstricks[*] por \TRICKS[*]
  33.     $line =~ s/(\\[V|v]erb[\*]?[[:punct:]]{1}.+?)\\end\{pspicture/$1\\end\{TRICKS/g;           # cambiamos
  34.     $line =~ s/(\\[V|v]erb[\*]?[[:punct:]]{1}.+?)\\end\{postscript\}/$1\\end\{POSTRICKS\}/g;   # cambiamos
  35.  
  36.     # Cambiamos los comentarios en TeX cuando comienzen con %
  37.     $line =~ s/(\%.+?)\\endpspicture/$1\\ENDTRICKS/g;                    # cambiamos
  38.     $line =~ s/(\%.+?)\\begin\{pspicture/$1\\begin\{TRICKS/g;            # cambiamos
  39.     $line =~ s/(\%.+?)\\begin\{postscript\}/$1\\begin\{POSTRICKS\}/g;    # cambiamos
  40.  
  41.     push( @preamb, $line );            # las unimos
  42. }
  43.  
  44. # Aquí tengo un problema, agrega una línea en blanco extra luego de unir los ficheros
  45.  
  46. my $modificado = join( "\n", $uno . '\begin{document}', @preamb );       #pegamos
  47.  
  48. open( AS, ">", $salida );              # creo el Archivo Salida
  49. print AS $modificado;                  # imprimo uno modificado
  50. close AS;                              # cierro
  51. exit;                                  # terminamos
  52.  
  53.  
Coloreado en 0.004 segundos, usando GeSHi 1.0.8.4
Y Ahora viene mis consultas:
  • La expresión regular $line =~ s/(\\[V|v]erb[\*]?[[:punct:]]{1}.+?)\\pspicture/$1\\TRICKS/g; no funciona bien, no es del todo correcta: si encuentra la expresión más de una vez solo cambia la primera (a veces), por ejemplo, con esta línea falla:
    Sintáxis: [ Descargar ] [ Ocultar ]
    Using latex Syntax Highlighting
    1. texto \verb*|\pspicture(algo)| \verb*|\pspicture*(algo)|resto linea
    Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4
    Hice algunos intentos pero fallaba si se presentaba este caso:
    Sintáxis: [ Descargar ] [ Ocultar ]
    Using latex Syntax Highlighting
    1. texto \verb*|algo ...\pspicture(algo)...\pspicture(algo)...algo| texto \pstricks(algo)
    Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4
    puesto que cambiaba todo lo que estuviera en esa línea. Sé que las expresiones que busco tienen siempre la forma:
    Sintáxis: [ Descargar ] [ Ocultar ]
    1. \verb*(carácter)...código...\pstricks(algo) (una más veces) ...código(carácter) 
    2. \verb(carácter)...código...\pspicture(algo) (una más veces) ...código(carácter) 
    donde (carácter) es un único (|,+,!,",',etc) y aparece al principio, inmediatamente después de \verb o \verb* y al final de la cadena, sin repetirce dentro de ésta. Y aquí va mi primera pregunta:
    ¿Cómo modifico la expresión para que cambie lo que quiero (las veces que aparezca) pero sólo dentro de éstos caracteres únicos?
    (aclaro que el que se dé este caso es muy extraño, pero posible).
  • La expresión regular $line =~ s/(\%.+?)\\pspicture/$1\\TRICKS/g; falla si no va un espacio después de "%" y aparece más de una vez en la misma línea. En este caso "SÍ" deseo que cambie todas las ocurrencias en la línea que encuentre la expresión (de principio a fin) y la pregunta de rigor: ¿Cómo modifico la expresión para que cambie lo que quiero con o sin espacios de principio a fin de línea? o mejor dicho ¿están correctas esas expresiones? es decir, ¿capturan lo que yo creo... o solo es mi imaginación?
Agradecido de antemano:

Pablo
Última edición por pablgonz el 2013-11-17 10:13 @467, editado 3 veces en total
pablgonz
Perlero nuevo
Perlero nuevo
 
Mensajes: 236
Registrado: 2010-09-08 21:03 @919
Ubicación: Concepción (Chile)

Publicidad

Re: Acotar expresión regular

Notapor explorer » 2013-11-16 13:27 @602

¿Seguro que ese es el archivo de entrada? Parece que dentro de él está la explicación de lo que tienes que hacer. Y eso complica la solución.

Por favor, reedita tu mensaje, en caso de que no sea así.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Acotar expresión regular

Notapor pablgonz » 2013-11-16 22:12 @966

Gracias por la pronta respuesta, explorer, edité el mensaje para aclarar mi dificultad.

Saludos.
pablgonz
Perlero nuevo
Perlero nuevo
 
Mensajes: 236
Registrado: 2010-09-08 21:03 @919
Ubicación: Concepción (Chile)

Re: Acotar expresión regular

Notapor explorer » 2013-11-17 10:56 @497

Estás procesando el cuerpo por líneas, pero, ¿podría darse el caso de que una parte '\verb ....' abarcara más de una línea? Por ejemplo:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
Los entornos pstricks se inician \verb|\pspicture(argumento)
o \pspicture*(argumento)| para plain TeX
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4
En ese caso, tu programa fallará.

No me queda claro el tratamiento a dar a los comentarios. Supongo que se refiere a las partes que comienzan por '%' pero que siguen estando dentro de un '\verb ...'. O sea: no hay que modificar los comentarios de ninguna manera (las líneas que comienzan por '%').
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Acotar expresión regular

Notapor pablgonz » 2013-11-17 12:54 @579

explorer escribiste:¿podría darse el caso de que una parte '\verb ....' abarcara más de una línea?
La verdad no... el archivo es (La)TeX y eso no está permitido, \verb es solo para códigos en una misma línea.

explorer escribiste:No me queda claro el tratamiento a dar a los comentarios. Supongo que se refiere a las partes que comienzan por '%' pero que siguen estando dentro de un '\verb ...'. O sea: no hay que modificar los comentarios de ninguna manera (las líneas que comienzan por '%').
El signo % se comporta en (La)TeX de la misma forma que # en Perl.

Por ejemplo:
Sintáxis: [ Descargar ] [ Ocultar ]
Using latex Syntax Highlighting
%\pspicture o \begin{pspicture}
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
deseo que lo convierta a:
Sintáxis: [ Descargar ] [ Ocultar ]
Using latex Syntax Highlighting
%\TRICKS o \begin{TRICKS}
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
no importando los caracteres o espacios que van después de %.

Ahora, si se diera este caso:
Sintáxis: [ Descargar ] [ Ocultar ]
Using latex Syntax Highlighting
\verb+%\pspicture o \begin{pspicture}+
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
solo debería cambiar:
Sintáxis: [ Descargar ] [ Ocultar ]
Using latex Syntax Highlighting
\verb+%\TRICKS o \begin{TRICKS}+
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Espero que esta aclaración sea útil.
Agradecido,
Pablo
Última edición por pablgonz el 2013-11-17 13:22 @599, editado 1 vez en total
pablgonz
Perlero nuevo
Perlero nuevo
 
Mensajes: 236
Registrado: 2010-09-08 21:03 @919
Ubicación: Concepción (Chile)

Re: Acotar expresión regular

Notapor explorer » 2013-11-17 13:18 @595

Disculpa. Dices que no quieres que haya modificación cuando se está dentro de \verb, pero el caso es que sí lo has hecho en el último ejemplo... ¿O acaso te refieres a un caso muy específico? Entonces, ¿qué distingue a ese caso específico de la regla general de no hacer modificaciones con % dentro de \verb?
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Acotar expresión regular

Notapor pablgonz » 2013-11-17 13:29 @603

Tienes razón, borré el error de redacción que tenía más arriba. Con el ejemplo espero que se entienda la idea... en mi mente va así:

Primero:
1. Busco \verb (o verb*) seguido de un solo carácter (+, /, !, etc.)
2. Seguido de (+, /, !, etc.) busco todas las apariciones y las cambio hasta llegar a (+, /, !, etc.)
3. Repito esto dentro de la misma línea por si existe más de un \verb

Segundo:
1. Busco todas la líneas que comienzan por % y veo si contienen lo que deseo y lo cambio

Acorde a mi lógica, si se ejecuta "Primero" y luego "Segundo" no tendría problemas dentro de \verb, ya estaría cambiado por "Primero".

Espero y sea de ayuda.
Pablo
pablgonz
Perlero nuevo
Perlero nuevo
 
Mensajes: 236
Registrado: 2010-09-08 21:03 @919
Ubicación: Concepción (Chile)

Re: Acotar expresión regular

Notapor explorer » 2013-11-17 13:51 @619

Creo que he encontrado una solución:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. use v5.16;
  3. use autodie;
  4.  
  5. @ARGV == 1 or die "Uso: $0 <archivo LaTeX a procesar\n";
  6.  
  7. my $nombre_archivo_entrada = shift;
  8. my $nombre_archivo_salida  = $nombre_archivo_entrada . '.tex';
  9.  
  10. -f $nombre_archivo_entrada or die "ERROR: No encuentro $nombre_archivo_entrada\n";
  11.  
  12.  
  13. ## Lectura del archivo
  14. open my $ENTRADA, '<', $nombre_archivo_entrada;
  15. undef $/;                                                       # modo 'slurp'
  16. my $archivo_entrada = <$ENTRADA>;
  17. close   $ENTRADA;
  18.  
  19.  
  20. ## Partición del documento
  21. my($cabeza,$cuerpo,$final) = $archivo_entrada =~ m/\A (.+? ^\\begin{document}) \s* (.+?) \s* (^ \\end{document}) \s* \z/msx;
  22.  
  23.  
  24. ## Cambios a realizar
  25. my %cambios = (
  26.     '\pspicture'                => '\TRICKS',
  27.     '\endpspicture'             => '\ENDTRICKS',
  28.  
  29.     '\begin{pspicture'          => '\begin{TRICKS',
  30.     '\end{pspicture'            => '\end{TRICKS',
  31.  
  32.     '\postscript'               => '\POSTRICKS',
  33.  
  34.     '\begin{postscript}'        => '\begin{POSTRICKS}',
  35.     '\end{postscript}'          => '\end{POSTRICKS}',
  36. );
  37.  
  38.  
  39. ## Cambiar
  40. while ($cuerpo =~ m/\\verb \*? ([[:punct:]]) (.+?) \1 | ^ \s* (\%) (.+?) $/gimsx) {     # buscamos un verbo o un comentario
  41.  
  42.     my($pos_inicial, $pos_final) = ($-[0], $+[0]);                      # posiciones
  43.     my $verbo = ${^MATCH};                                              # el verbo encontrado
  44.  
  45. #    my $interior = $2;
  46. #    next if $interior =~ m/^ \s* \%/x;                                 # no hacemos modificaciones si es un comentario dentro de \verb
  47.  
  48.     while (my($busco, $cambio) = each %cambios) {                       # buscar y cambiar
  49.    
  50.         $verbo =~ s/\Q$busco\E/$cambio/g;                               # es necesario escapar $busco, ya que contiene
  51.                                                                         # caracteres extraños
  52.     }
  53.  
  54.     substr $cuerpo, $pos_inicial, $pos_final-$pos_inicial, $verbo;      # insertamos los nuevos cambios
  55.    
  56.     pos($cuerpo)= $pos_inicial + 4;                                     # reposicionamos la búsqueda del siguiente verbo
  57.                                                                         # empezando en donde lo encontramos, pero un poco más allá
  58. }
  59.  
  60.  
  61. ## Escritura del resultado
  62. open my $SALIDA, '>', $nombre_archivo_salida;
  63. print   $SALIDA "$cabeza\n$cuerpo\n$final\n";
  64. close   $SALIDA;
Coloreado en 0.004 segundos, usando GeSHi 1.0.8.4
El resultado es:
Sintáxis: [ Descargar ] [ Ocultar ]
Using latex Syntax Highlighting
  1. \documentclass{article}
  2. \usepackage{pstricks-add}
  3. \newenvironment{postscript}{}{}
  4. \begin{document}
  5. Los entornos pstricks se inician \verb|\TRICKS(argumento) o \TRICKS*(argumento)| para plain TeX
  6. y \verb+\begin{TRICKS} o \begin{TRICKS*}+ para LaTeX, antes o después de cada entorno, es necesario
  7. definir \verb'\psset{opciones}' por ejemplo:
  8. \verb+\psset{opciones}\begin{TRICKS}+ o \verb-\begin{TRICKS}\psset{opciones}- y para cerrar los entornos usamos
  9. (dependiendo) \verb*'\ENDTRICKS' para plain TeX y \verb*#\end{TRICKS} o \end{TRICKS*}# para LaTeX.
  10. Algunas ocasiones es necesario definir un nuevo entorno para incluir nuestras definiciones dentro de el, por
  11. ejemplo \verb<\newenvironment{postscript}{}{}< e incluir nuestros entornos dentro de el, es decir, las lineas deben ser
  12. \verb|\begin{POSTRICKS} \psset{opciones} \begin{TRICKS}| o \verb|\begin{POSTRICKS} \begin{TRICKS} \psset{opciones}|
  13. pero no \verb|\psset{opciones}\begin{POSTRICKS}\begin{TRICKS}| o \verb|\psset{opciones}\begin{TRICKS}\begin{POSTRICKS}|
  14. y para cerrar el entorno usamos \verb&\end{POSTRICKS}&. Para comentar una linea puedes usar \verb|%| antes de cada linea
  15. por ejemplo \verb|% \TRICKS*(argumento) o %\TRICKS*(argumento) o %%%%\TRICKS*(argumento)|. Veamos algunos ejemplos:
  16.  
  17. %\begin{POSTRICKS}
  18. \begin{postscript}
  19. \psset{unit=1.0cm}
  20. \begin{pspicture}[showgrid=true](4,2)
  21.   \psscaleboxto(8,2){foo bar baz}
  22. \end{pspicture}
  23. \end{postscript}
  24.  
  25. \begin{pspicture*}(4,2)(8,1)
  26. \psset{unit=1.0cm}
  27. \psscaleboxto(8,2){foo bar baz}
  28. \end{pspicture*}
  29.  
  30. %%% \TRICKS*(4,2)(8,1) o \begin{TRICKS*}(4,2)(8,1)
  31. \pspicture*(4,2)(8,1)
  32. \psset{unit=1.0cm}
  33. \psscaleboxto(8,2){foo bar baz}
  34. \endpspicture
  35. % se puede \ENDTRICKS o \end{TRICKS*}
  36. % \TRICKS(4,2)(8,1) o \begin{TRICKS}(4,2)(8,1)
  37. \pspicture(4,2)(8,1)
  38. \psset{unit=1.0cm}
  39. \psscaleboxto(8,2){foo bar baz}
  40. \endpspicture
  41. %\ENDTRICKS o \end{TRICKS}
  42. \end{document}
Coloreado en 0.003 segundos, usando GeSHi 1.0.8.4

La idea es localizar las partes del documento con un '\verb ...', extraerlas, modificarlas con los cambios que queremos, y finalmente, colocar los nuevos cambios en el documento.

Con más detalle...
  • [2] gracias a que estamos en un Perl v5.16, no necesitamos activar los warnings y el modo estricto, porque quedan activado por defecto
  • [14-17] leemos todo el archivo a memoria
  • [21] partimos el documento en las tres partes principales, usando una expresión regular
  • [25-36] definimos lo que queremos cambiar. En este caso son literales por literales
  • [40-58] bucle que realiza los cambios mientras encontremos '\verb ...'
  • [42-43] extraemos los datos de posición y la propia cadena del '\verb ...' encontrado
  • [48-52] aplicamos todos los cambios definidos antes
  • [50] con un operador de sustitución. Aquí ponemos '\Q...\E' para pedirle a Perl que "escape" los caracteres peligrosos que pudieran existir en lo que $busco. Y esa sustitución se hace a lo largo de todo el $verbo
  • [54] insertamos en $cuerpo, en la $pos_inicial, el nuevo $verbo cambiado, sustituyendo a lo que había antes
  • [56] reanudamos la búsqueda, en la misma posición donde encontramos '\verb ...', pero un poco más allá (a continuación de '\verb')
  • [62-64] grabamos el resultado
La clave está, primero, en hacer una operación de sustitución sólo en la cadena que nos interesa, y segundo, usar la facultad de substr() de cambiar un conjunto de caracteres por otro. En la línea 51 indicamos la posición inicial y el largo de la cadena a sustituir (el $verbo encontrado antes), y le pasamos un cuarto argumento más, que es la nueva cadena de caracteres. substr() se encargará de recortar o hacer el sitio suficiente para acomodar los cambios.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Acotar expresión regular

Notapor pablgonz » 2013-11-17 14:52 @661

Como dicen en argentina... SOS UN MONSTRUO. Esta solución está más allá de mis capacidades actuales. Pensé que podría lograrlo yo mismo usando solo expresiones regulares (y extendidas) pero, claramente no pude.

Y como de costumbre, un par de interrogantes:
1. Si deseo que busque en otras expresión, distinta de \verb, por ejemplo \lst, pero, que cumple con las mismas condiciones, ¿debo definir un nuevo bucle? ¿O solo copio la línea cambiando \verb por \lst?

2. (Creo que esto no es posible) Supongamos que el archivo de entrada cumple con las condiciones anteriores y se agrega esto:
Sintáxis: [ Descargar ] [ Ocultar ]
Using latex Syntax Highlighting
  1. \documentclass{article}
  2. \usepackage{pstricks-add}
  3. \usepackage{fancyvrb}
  4. \newenvironment{postscript}{}{}
  5. \begin{document}
  6. Los entornos pstricks se inician \verb|\pspicture(argumento) o \pspicture*(argumento)| para plain TeX
  7. y \verb+\begin{pspicture} o \begin{pspicture*}+ para LaTeX, antes o después de cada entorno, es necesario
  8. definir \verb'\psset{opciones}' por ejemplo:
  9. \DefineShortVerb[]{\|}
  10. Usamos el delimitador barra |\begin{pspicture} o \begin{pspicture*}| ...
  11. ahora lo cambiamos indefinimos
  12. \UndefineShortVerb{\|}
  13. y ahora definimos el (mas)+
  14. \DefineShortVerb[]{\+}
  15. Usamos el delimitador mas +\begin{pspicture} o \begin{pspicture*}+ ...
  16. \UndefineShortVerb{\+}
  17. y ahora definimos el (almoadilla)
  18. \DefineShortVerb[]{\#}
  19. Usamos el delimitador almoadilla #\begin{pspicture} o \begin{pspicture*}# ...
  20. %%% \pspicture*(4,2)(8,1) o \begin{pspicture*}(4,2)(8,1)
  21. \pspicture*(4,2)(8,1)
  22. \psset{unit=1.0cm}
  23. \psscaleboxto(8,2){foo bar baz}
  24. \endpspicture
  25. % se puede \endpspicture o \end{pspicture*}
  26. % \pspicture(4,2)(8,1) o \begin{pspicture}(4,2)(8,1)
  27. \pspicture(4,2)(8,1)
  28. \psset{unit=1.0cm}
  29. \psscaleboxto(8,2){foo bar baz}
  30. \endpspicture
  31. %\endpspicture o \end{pspicture}
  32. \end{document}
  33.  
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
Es decir, al final de la línea \DefineShortVerb[]{\|} (justo antes de }) define el carácter de inicio y fin de donde debo buscar para cambiar, donde los corchetes [] son opcionales, pero, ahora sin \verb y la línea \UndefineShortVerb{\|} si es que está presente me permite cambiar el delimitador a uno nuevo. Las expresiones dentro de los delimitadores se comportan de igual manera que en \verb, pero, el delimitador puede ir cambiando dentro del archivo.

En mi mente sería algo así:

1. Primero recorro todas las líneas con el script que me dejaste arriba.
2. Recorro nuevamente el archivo de la siguiente manera
2.a. Busco \DefineShortVerb[]{\|} y me quedo con lo que esté justo atrás de la llave de cierre, en este caso "|"
2.b. Efectuó un reemplazo idéntico a lo que hacía en \verb, como verb|...| ya está cambiado no le pasara nada, hasta que encuentre la línea \UndefineShortVerb{\|}. Si es que está presente sigo en 3, si no, termino
3. Vuelvo a iniciar el proceso desde la línea en que se encontraba \UndefineShortVerb{\|} (si es que estaba) busco la siguiente aparición de \DefineShortVerb[]{\+} y repito esto hasta el final del documento

¿Es esto posible? Sería el ideal... para lo que busco.

Agradecido por la solución y la explicación (ese es el plus de tus respuestas).

Pablo
pablgonz
Perlero nuevo
Perlero nuevo
 
Mensajes: 236
Registrado: 2010-09-08 21:03 @919
Ubicación: Concepción (Chile)

Re: Acotar expresión regular

Notapor explorer » 2013-11-17 19:10 @840

Debido a que estamos usando una expresión regular para ir analizando el $cuerpo, si podemos ampliarla, podemos seguir usándola para analizar el texto poco a poco.

Con la siguiente solución se contempla el caso de definir delimitadores en donde miraremos para hacer los cambios:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. use v5.16;
  3. use autodie;
  4.  
  5. @ARGV == 1 or die "Uso: $0 <archivo LaTeX a procesar\n";
  6.  
  7. my $nombre_archivo_entrada = shift;
  8. my $nombre_archivo_salida  = $nombre_archivo_entrada . '.tex';
  9.  
  10. -f $nombre_archivo_entrada or die "ERROR: No encuentro $nombre_archivo_entrada\n";
  11.  
  12.  
  13. ## Lectura del archivo
  14. open my $ENTRADA, '<', $nombre_archivo_entrada;
  15. undef $/;                                                       # modo 'slurp'
  16. my $archivo_entrada = <$ENTRADA>;
  17. close   $ENTRADA;
  18.  
  19.  
  20. ## Partición del documento
  21. my($cabeza,$cuerpo,$final) = $archivo_entrada =~ m/\A (.+? ^\\begin{document}) \s* (.+?) \s* (^ \\end{document}) \s* \z/msx;
  22.  
  23.  
  24. ## Cambios a realizar
  25. my %cambios = (
  26.     '\pspicture'                => '\TRICKS',
  27.     '\endpspicture'             => '\ENDTRICKS',
  28.  
  29.     '\begin{pspicture'          => '\begin{TRICKS',
  30.     '\end{pspicture'            => '\end{TRICKS',
  31.  
  32.     '\postscript'               => '\POSTRICKS',
  33.  
  34.     '\begin{postscript}'        => '\begin{POSTRICKS}',
  35.     '\end{postscript}'          => '\end{POSTRICKS}',
  36. );
  37.  
  38. ## Cambiar
  39. my $nodel = "\0";
  40. my $del = $nodel;
  41.  
  42. while ($cuerpo =~
  43.     /   (?<pre>\\verb \*? (?<del>[[:punct:]])) .+? \g{del}              # busca \verb con delimitador
  44.     | ^ (?<pre>\s* \%+) .+? $                                           # busca en comentarios
  45.     |   (?<pre>$del) .+? $del                                           # busca texto delimitado
  46.     |   (?<pre>\\(?:Un)?DefineShortVerb)(?:\[\])?{(?<del>.+?)}          # (in)define delimitadores
  47.     /gimsx) {
  48.  
  49.     my($pos_inicial, $pos_final) = ($-[0], $+[0]);                      # posiciones
  50.     my $verbo = ${^MATCH};                                              # el verbo encontrado
  51.     my $pre   = $+{pre};                                                # partícula inicial
  52.  
  53.     if (lc($pre) eq '\defineshortverb') {                               # definimos delimitador
  54.         $del = $+{del};
  55.         next;
  56.     }
  57.     elsif (lc($pre) eq '\undefineshortverb') {                          # indefinimos delimitador
  58.         $del = $nodel;
  59.         next;
  60.     }
  61.  
  62.     while (my($busco, $cambio) = each %cambios) {                       # buscar y cambiar
  63.    
  64.         $verbo =~ s/\Q$busco\E/$cambio/g;                               # es necesario escapar $busco, ya que contiene
  65.                                                                         # caracteres extraños
  66.     }
  67.  
  68.     substr $cuerpo, $pos_inicial, $pos_final-$pos_inicial, $verbo;      # insertamos los nuevos cambios
  69.    
  70.     pos($cuerpo)= $pos_inicial + length $pre;                           # reposicionamos la búsqueda del siguiente verbo
  71.                                                                         # empezando en donde lo encontramos, pero un poco más allá
  72. }
  73.  
  74.  
  75. ## Escritura del resultado
  76. open my $SALIDA, '>', $nombre_archivo_salida;
  77. print   $SALIDA "$cabeza\n$cuerpo\n$final\n";
  78. close   $SALIDA;
Coloreado en 0.003 segundos, usando GeSHi 1.0.8.4

En cuanto a las preguntas que haces,
1. cambia 'verb' por '(?:verb|lst)' en la primera expresión regular
2. sí es posible hacerlo, siempre y cuando lo que queramos hacer se pueda expresar en forma de reglas; y sepamos traducir esas reglas a expresiones regulares
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Siguiente

Volver a Básico

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 10 invitados

cron