• 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.

Re: Acotar expresión regular

Notapor pablgonz » 2013-11-17 22:32 @980

Muchísimas gracias, explorer... Me percaté de que mi primera consulta era posible, pero, no doy con la modificación necesaria siguiendo tus instrucciones (demasiados paréntesis para mi), me explico un poco:

Para \verb, se tienen solo dos opciones antes de que empiece el lugar donde quiero hacer el reemplazo, las opciones son \verb o \verb*; * es opcional.

Para \lstinline se tienen solo dos opciones antes de que empiece el lugar donde hacer el reemplazo, las opciones son \lstinline o \lstinline[algo]; [algo] es opcional.

Para \mint se tienen solo dos opciones antes de que empiece el lugar donde quiero reemplazar \mint[algo]{otro} o \mint{otro}, donde [algo] es opcional y {otro} es obligatorio.

Lógicamente todos los reemplazos siguen el mismo patrón ya descrito.

Con la respuesta a la segunda pregunta... me dejas impactado, había tratado de comprender ese tipo de expresiones y tenía la duda de si hacer esto era posible, pero, nunca las comentan en la red y se me hace un poco difícil entenderlas.

Como siempre comentas lo códigos, es mucho más fácil memorizarlas y comprender qué es lo que están haciendo. Modifiqué un par de líneas, pero, no funciona como lo deseo (el código que propones también falla), me explico:

\DefineShortVerb{\carácter} y \UndefineShortVerb{\caracter} son siempre de esta forma: {\caracter} siempre lleva la barra "\" antes carácter y jamas va [corchete]; de hecho, "[" se puede usar como carácter delimitador. Usando la misma idea traté de definir otras palabras, de este estilo, para efectuar el reemplazo que necesito, por ejemplo:

Como inicio (lo mismo que \DefineShortVerb{\carácter}):
\lstMakeShortInline[algo]{carácter} donde [algo] es opcional y carácter no lleva la barra "\" y \lstDeleteShortInline{carácter} es siempre de ésta forma.

Aquí dejo un ejemplo con lo que debería cambiar y lo que debería mantenerse... a ver si me dan una ayuda más para lograr lo que deseo:
Sintáxis: [ Descargar ] [ Ocultar ]
Using latex Syntax Highlighting
  1. \documentclass{article}
  2. \usepackage{fancyvrb}
  3. \usepackage{listings}
  4. \usepackage{minted}
  5. \usepackage{pstricks-add}
  6. \newenvironment{postscript}{}{}
  7. \begin{document}
  8. Usamos \verb|\begin{pspicture} o \begin{pspicture*}| o \verb*|\begin{pspicture} o \begin{pspicture*}| (cambia)
  9. esta linea debería quedar intacta \begin{pspicture} o \begin{pspicture*}
  10. % esta linea debería modificarse \begin{pspicture} o \begin{pspicture*}
  11. Usamos \lstinline[hola]+\begin{pspicture} o \begin{pspicture*}+ y seguimos (cambia)
  12. Usamos \lstinline-\begin{pspicture} o \begin{pspicture*}- y seguimos (cambia)
  13. Esta linea deberia quedar intacta \lstinline*[hola]+\begin{pspicture} o \begin{pspicture*}+ (no cumple por *)
  14. esta linea debería quedar intacta \begin{pspicture} o \begin{pspicture*}
  15. % esta linea debería modificarse \begin{pspicture} o \begin{pspicture*}
  16. Usamos \mint{algo}$\begin{pspicture} o \begin{pspicture*}$ y seguimos (cambia)
  17. Usamos \mint[hola]{algo}$\begin{pspicture} o \begin{pspicture*}$ y seguimos (cambia)
  18. Esta linea debería quedar intacta \mint[holas]#\begin{pspicture} o \begin{pspicture*}# (no cumple falta {})
  19. Esta linea debería quedar intacta \mint*#\begin{pspicture} o \begin{pspicture*}# (no cumple por *)
  20. esta linea debería quedar intacta \begin{pspicture} o \begin{pspicture*}
  21. % esta linea debería modificarse \begin{pspicture} o \begin{pspicture*}
  22.  
  23. \section{ShortVerb}
  24. \DefineShortVerb{\|}
  25. Usamos el delimitador barra |\begin{pspicture} o \begin{pspicture*}| (cambia)
  26. esta linea debería quedar intacta \begin{pspicture} o \begin{pspicture*}
  27. ahora lo cambiamos indefinimos
  28. %esta deberia cambiar \begin{pspicture} o \begin{pspicture*}
  29. \UndefineShortVerb{\|}
  30. y ahora definimos el (mas)+
  31. \DefineShortVerb{\+}
  32. Usamos el delimitador mas +\begin{pspicture} o \begin{pspicture*}+ (cambia)
  33. esta linea debería quedar intacta \begin{pspicture} o \begin{pspicture*}
  34. \UndefineShortVerb{\+}
  35. y ahora definimos el (almoadilla)
  36. \DefineShortVerb{\#}
  37. Usamos el delimitador almoadilla #\begin{pspicture} o \begin{pspicture*}# (cambia)
  38. esta linea debería quedar intacta \begin{pspicture} o \begin{pspicture*}
  39.  
  40. \section{ShortInline}
  41. \lstMakeShortInline[algo]{|}
  42. Usamos el delimitador barra |\begin{pspicture} o \begin{pspicture*}| (cambia)
  43. esta linea debería quedar intacta \begin{pspicture} o \begin{pspicture*}
  44. ahora lo cambiamos indefinimos
  45. \lstDeleteShortInline{|}
  46. y ahora definimos el (mas)+
  47. \lstMakeShortInline[algo]{+}
  48. Usamos el delimitador mas +\begin{pspicture} o \begin{pspicture*}+ (cambia)
  49. esta linea debería quedar intacta \begin{pspicture} o \begin{pspicture*}
  50. \lstDeleteShortInline{+}
  51. y ahora definimos el (almoadilla)
  52. \lstMakeShortInline[algo]{#}
  53. Usamos el delimitador almoadilla #\begin{pspicture} o \begin{pspicture*}# (cambia)
  54. esta linea debería quedar intacta \begin{pspicture} o \begin{pspicture*}
  55.  
  56. %\begin{postscript} debería cambiar
  57. \begin{postscript} % queda =
  58. \psset{unit=1.0cm}
  59. \begin{pspicture}[showgrid=true](4,2)% queda =
  60.   \psscaleboxto(8,2){foo bar baz}
  61. \end{pspicture}% queda =
  62. \end{postscript}% queda =
  63.  
  64. \begin{pspicture*}(4,2)(8,1)% queda =
  65. \psset{unit=1.0cm}
  66. \psscaleboxto(8,2){foo bar baz}
  67. \end{pspicture*}% queda =
  68.  
  69. %%% \pspicture*(4,2)(8,1) o \begin{pspicture*}(4,2)(8,1) debería cambiar
  70. \pspicture*(4,2)(8,1)% queda =
  71. \psset{unit=1.0cm}
  72. \psscaleboxto(8,2){foo bar baz}
  73. \endpspicture% queda =
  74. % se puede \endpspicture o \end{pspicture*} debería cambiar
  75. % \pspicture(4,2)(8,1) o \begin{pspicture}(4,2)(8,1) debería cambiar
  76. \pspicture(4,2)(8,1)% queda =
  77. \psset{unit=1.0cm}
  78. \psscaleboxto(8,2){foo bar baz}
  79. \endpspicture% queda =
  80. %\endpspicture o \end{pspicture} debería cambiar
  81. \end{document}
Coloreado en 0.003 segundos, usando GeSHi 1.0.8.4

P.D.: Ahora me acuerdo por qué puse como título del tema "Acotar expresión regular"... me refería a esto...
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-18 10:20 @472

A medida de que van apareciendo más detalles, el programa se va complicando.

Ajustando las reglas fuera de la expresión regular reducimos el problema grande en otros más pequeños.

El siguiente ejemplo soluciona el último problema planteado.
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. ## Variables y constantes
  40. my $no_del = "\0";
  41. my $del    = $no_del;
  42.  
  43. ## Reglas
  44. my $llaves      = qr/\{ .+? \}                                                                  /x;
  45. my $no_corchete = qr/(?:\[ .+? \])?                                                             /x;
  46. my $delimitador = qr/\{ (?<del>.+?) \}                                                          /x;
  47. my $verb        = qr/verb [*]?                                                                  /ix;
  48. my $lst         = qr/lstinline (?!\*) $no_corchete                                              /ix;
  49. my $mint        = qr/mint      (?!\*) $no_corchete $llaves                                      /ix;
  50. my $marca       = qr/\\ (?:$verb | $lst | $mint) (\S) .+? \g{-1}                                /x;
  51. my $comentario  = qr/^ \s* \%+ .+? $                                                            /mx;
  52. my $definedel   = qr/\\ (?:   DefineShortVerb | lstMakeShortInline  ) $no_corchete $delimitador /ix;
  53. my $indefinedel = qr/\\ (?: UndefineShortVerb | lstDeleteShortInline) $llaves                   /ix;
  54.  
  55.  
  56. ## Cambiar
  57. while ($cuerpo =~
  58.     /   $marca
  59.     |   $comentario
  60.     |   $definedel
  61.     |   $indefinedel
  62.     |   $del .+? $del                                                           # delimitado
  63.     /gimx) {
  64.  
  65.     my($pos_inicial, $pos_final) = ($-[0], $+[0]);                              # posiciones
  66.     my $encontrado = ${^MATCH};                                                 # lo encontrado
  67.  
  68.     given ($encontrado) {
  69.         when (/$definedel/) {                                                   # definimos delimitador
  70.             $del = $+{del};
  71.             $del = "\Q$+{del}" if substr($del,0,1) ne '\\';                     # es necesario "escapar" el delimitador
  72.         }
  73.         when (/$indefinedel/) {                                                 # indefinimos delimitador
  74.             $del = $no_del;
  75.         }
  76.         default {                                                               # Aquí se hacen los cambios
  77.             while (my($busco, $cambio) = each %cambios) {
  78.  
  79.                 $encontrado =~ s/\Q$busco\E/$cambio/g;                          # es necesario escapar $busco, ya que contiene caracteres extraños
  80.             }
  81.  
  82.             substr $cuerpo, $pos_inicial, $pos_final-$pos_inicial, $encontrado; # insertamos los nuevos cambios
  83.  
  84.             pos($cuerpo)= $pos_inicial + length $encontrado;                    # reposicionamos la siguiente búsqueda
  85.         }
  86.     }
  87. }
  88.  
  89.  
  90. ## Escritura del resultado
  91. open my $SALIDA, '>', $nombre_archivo_salida;
  92. print   $SALIDA "$cabeza\n$cuerpo\n$final\n";
  93. close   $SALIDA;
  94.  
  95. __END__
Coloreado en 0.004 segundos, usando GeSHi 1.0.8.4
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-18 23:36 @025

Eres un genio, funciona a la perfección, supongo que si deseo hacer el proceso inverso, es decir, que vuelva todo a como estaba antes, lo puedo definir como una función (subrun) dentro de otro script. Tengo una última consulta, pero, no sé si va en este mismo hilo, la planteo porque la solución (según yo) va por una idea parecida a las expresiones que me mostraste en la solución de este problema. Va así, supongamos que dentro del mismo archivo de entrada, contiene lo siguiente:
Sintáxis: [ Descargar ] [ Ocultar ]
Using latex Syntax Highlighting
  1. \begin{example}{below,algo=algo,etc}
  2. \includegraphics[scale=1]{archivo-fig-1}
  3. \end{example}
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4
me interesan dos cosas, la frase incluida en {...}:
Sintáxis: [ Descargar ] [ Ocultar ]
Using latex Syntax Highlighting
  1. below
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4
y la línea
Sintáxis: [ Descargar ] [ Ocultar ]
Using latex Syntax Highlighting
  1. \includegraphics[scale=1]{archivo-fig-1}
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4
Deseo hacer lo siguiente (si es que es posible)
si encuentra la frase "right" cambia el código a esto:
Sintáxis: [ Descargar ] [ Ocultar ]
Using latex Syntax Highlighting
  1. \begin{example}{right,hmargin=1,algo=algo,etc}
  2. \includegraphics[scale=1]{archivo-fig-1}
  3. \tcblower
  4. \lstinputlisting[linerange=document-document]{images/archivo-fig-1.tex}
  5. \end{example}
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4

si encuentra la frase "left" cambia el código a esto:
Sintáxis: [ Descargar ] [ Ocultar ]
Using latex Syntax Highlighting
  1. \begin{example}{left,hmargin=1,algo=algo,etc}
  2. \lstinputlisting[linerange=document-document]{images/archivo-fig-1.tex}
  3. \tcblower
  4. \includegraphics[scale=1]{archivo-fig-1}
  5. \end{example}
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4

si encuentra la frase "above" cambia a esto:
Sintáxis: [ Descargar ] [ Ocultar ]
Using latex Syntax Highlighting
  1. \begin{example}{above,hmargin=1,algo=algo,etc}
  2. \lstinputlisting[linerange=document-document]{images/archivo-fig-1.tex}
  3. \tcblower
  4. \includegraphics[scale=1]{archivo-fig-1}
  5. \end{example}
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4

y si encuentra la frase "below" cambia a esto:
Sintáxis: [ Descargar ] [ Ocultar ]
Using latex Syntax Highlighting
  1. \begin{example}{below,hmargin=1,algo=algo,etc}
  2. \includegraphics[scale=1]{archivo-fig-1}
  3. \tcblower
  4. \lstinputlisting[linerange=document-document]{images/archivo-fig-1.tex}
  5. \end{example}
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4
En teoría es más menos parecido al problema anterior, el cual está TOTALMENTE solucionado (lo probé con muchos archivo...)
Agradecido,
Pablo.

PD: ¿Donde está el botón para dar por solucionado el tema?
Última edición por pablgonz el 2013-11-21 08:03 @377, editado 3 veces 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-19 12:33 @565

Usando el operador de sustitución, no deberías tener problemas.
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-20 11:46 @532

El proceso inverso SÍ lo logreé.. (creo) me doy un par de vueltas extra, pero, me funciona, el tema está en lo último...

Una vez que modifico y guardo el archivo, hago una llamada al sistema, corre un programa y éste me genera un fichero de salida, en el cual hago ésto:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. use v5.16;
  3. use autodie;
  4.  
  5. open my $IPDF,'<', "archivo-pdf.tex";
  6. undef $/;   # read all file
  7. my ($uno,$dos) = split(/\\begin\{document\}/,<$IPDF>,2);
  8. close $IPDF;
  9.        
  10. my @coment = split /\n/, $uno; # divido en dos
  11. my @preamb;
  12.  
  13. foreach my $line (@coment) {
  14.         chomp($line);
  15.                 $line =~ s/\\usepackage(?:\[.+?\])?\{pst.+?}//g;                # elimina
  16.                 $line =~ s/\\usepackage(?:\[.+?\])?\{psfr.+?}//g;               # elimina
  17.                 $line =~ s/(\\usepackage(?:\[.+?\])?)\{auto-fig.+?}//g;         # elimina
  18.                 $line =~ s/(\\usepackage(?:\[.+?\])?)\{vaucanson-.+?}//g;       # elimina
  19.                 $line =~ s/(\\usepackage(?:\[.+?\])?)\{psgo}//g;        # elimina
  20.                 $line =~ s/(\\usepackage(?:\[.+?\])?)\{graph/\%$1\{graph/g; # comenta
  21.         next if $line =~ m/^\s*$/; # elimina los espacios en blanco
  22.         push(@preamb,$line);}   # añado los cambios
  23.  
  24. my $clean = join("\n", @preamb, "\\usepackage{grfext}\n\\\PrependGraphicsExtensions*{pdf}\n\\usepackage{graphicx}\n\\graphicspath{{images/}}\n\\begin{document}". $dos);
  25.        
  26. open my $OPDF,'>',"archivo-pdf.tex"; # reescribimos los cambios
  27. print $OPDF $clean;
  28. close $OPDF;
  29.  
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4
y aquí es donde me pierdo. Mi idea es leer $dos al mismo tiempo y hacer los cambios que deseo, es decir, cambiar de esto:
Sintáxis: [ Descargar ] [ Ocultar ]
Using latex Syntax Highlighting
  1. \documentclass{article}
  2. \usepackage{tcolorbox}
  3. \usepackage{grfext}
  4. \PrependGraphicsExtensions*{pdf}
  5. \usepackage{graphicx}
  6. \graphicspath{images/}
  7. \begin{document}
  8. Texto
  9. \begin{myexample}{above, algo1,algo2}
  10. \includegraphics[scale=1]{archivo-fig-1}
  11. \end{myexample}
  12. Texto
  13. \begin{myexample}{below,algo1,algo2}
  14. \includegraphics[scale=0.5]{archivo-fig-2}
  15. \end{myexample}
  16. Texto
  17. \begin{myexample}{right,algo1,algo2}
  18. \includegraphics[scale=0.8]{archivo-fig-3}
  19. \end{myexample}
  20. Texto
  21. \begin{myexample}{left,algo1,algo2}
  22. \includegraphics[scale=1.2]{archivo-fig-4}
  23. \end{myexample}
  24. \end{document}
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
a esto:
Sintáxis: [ Descargar ] [ Ocultar ]
Using latex Syntax Highlighting
  1. \documentclass{article}
  2. \usepackage{tcolorbox}
  3. \usepackage{grfext}
  4. \PrependGraphicsExtensions*{pdf}
  5. \usepackage{graphicx}
  6. \graphicspath{images/}
  7. \begin{document}
  8. Texto
  9. \begin{myexample}{above,algo1,algo2}
  10. \lstinputlisting[linerange=document-document]{images/archivo-fig-1.tex}
  11. \tcblower
  12. \includegraphics[scale=1]{archivo-fig-1}
  13. \end{myexample}
  14. Texto
  15. \begin{myexample}{below,algo1,algo2}
  16. \includegraphics[scale=0.5]{archivo-fig-2}
  17. \tcblower
  18. \lstinputlisting[linerange=document-document]{images/archivo-fig-2.tex}
  19. \end{myexample}
  20. Texto
  21. \begin{myexample}{right,algo1,algo2}
  22. \includegraphics[scale=0.8]{archivo-fig-3}
  23. \tcblower
  24. \lstinputlisting[linerange=document-document]{images/archivo-fig-3.tex}
  25. \end{myexample}
  26. Texto
  27. \begin{myexample}{left,algo1,algo2}
  28. \lstinputlisting[linerange=document-document]{images/archivo-fig-4.tex}
  29. \tcblower
  30. \includegraphics[scale=1.2]{archivo-fig-4}
  31. \end{myexample}
  32. \end{document}
  33.  
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
Si puedo lograr ésto, el script estaría completo, es decir, podría integrarlo todo en uno.
Agradecido de antemano,
Pablo
Comentario:
Las palabras en las que quiero buscar están siempre al principio de cada línea, es decir
above, below, left, right están siempre dentro de "{...}" luego de \begin{myexample}.
"images" es un string referido a una carpeta bajo el directorio en el cual se ejecuta el
script.
He leido y revisado como unas ¿20? veces la expresión regular que pusiste más arriba, pero, no la he podido adaptar a lo que deseo...googlee un buen rato y este tipo de expresiones regulares son un tanto complicadas de entender. 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 pablgonz » 2013-11-21 16:57 @748

Estuve googleando un rato y revisando stackoverflow por si encontraba algún código que me fuese útil, pero, no encontré lo que necesitaba, solo ejemplos de cómo reemplazar una línea (sin opciones).

¿Me podías dar un esqueleto de código para lo que quiero hacer?
Saludos,
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-22 11:35 @524

El problema de tu código es que estás intentando resolverlo por líneas, y resulta que es un bloque de líneas los que hay que modificar. Aunque no es imposible, quizás lo más cómodo sea resolverlo procesando todo el archivo como un único conjunto de líneas.
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. my $archivo;
  16. {
  17.     local $/;
  18.     $archivo = <$ENTRADA>;
  19. }
  20. close   $ENTRADA;
  21.  
  22. ## cambiar
  23. $archivo =~
  24. s/(?<begin_inicio>\\begin\{ .+? \}\{) (?<posicion>above|left) (?<begin_resto>.+? \}) \s+
  25. (?<graphics>(?<graphics_inicio>\\includegraphics\[ .+? \]\{) (?<graphics_resto>.+?) \})
  26. /$+{begin_inicio}$+{posicion}$+{begin_resto}
  27. \\lstinputlisting[linerange=document-document]{images\/$+{graphics_resto}.tex}
  28. \\tcblower
  29. $+{graphics}/gmx;
  30.  
  31. $archivo =~
  32. s/(?<begin_inicio>\\begin\{ .+? \}\{) (?<posicion>below|right) (?<begin_resto>.+? \}) \s+
  33. (?<graphics>(?<graphics_inicio>\\includegraphics\[ .+? \]\{) (?<graphics_resto>.+?) \})
  34. /$+{begin_inicio}$+{posicion}$+{begin_resto}
  35. $+{graphics}
  36. \\tcblower
  37. \\lstinputlisting[linerange=document-document]{images\/$+{graphics_resto}.tex}/gmx;
  38.  
  39. ## Grabar
  40. open my $SALIDA, '>', $nombre_archivo_salida;
  41. print $SALIDA $archivo;
  42. close $SALIDA;
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4
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-23 02:36 @150

Haces ver el código tan sencillo, me estaba partiendo la cabeza con usar "index" y pensar en todas las posibles opciones... ufff. Aparte, sé que es "feo" y "no aceptado" usar "perl dentro de perl" (le he leído varias veces en el foro), con el par de script que me has proporcionado resuelvo varias tareas (que antes hacía en bash/sed y a mano). Se podrá adaptar el código a:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. open my $SALIDA,'>',"$nombre_archivo_salida";
  2. open my $ENTRADA,  '<', "$nombre_archivo_entrada";
  3.         while (<ENTRADA>) {
  4.            # Leemos todo y hacemos los cambios
  5.            print   $SALIDA "$cabeza\n$cuerpo\n$final\n";
  6.            }
  7. close $ENTRADA;
  8. close $SALIDA;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
para poder ingresarlo dentro de otro script, en este @ARGV[0] ya está definido:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. my @SuffixList = (".tex","",".ltx");    # posible extensión
  2. my ($name,$path,$ext) = fileparse($ARGV[0],@SuffixList);
  3. if ($ext eq "") { $ext = ".tex"; }  # extensión del archivo de entrada
  4. my $TeXfile = "$path$name$ext";
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
o en última instancia, usar:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. use File::Basename;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
para dividir el archivo de entrada por extensión nombre.tex y dejar fijo el archivo de salida a nombre-tmp.tex y usar el script por medio de una llamada a sistema (sé que es feo y no aceptado perlianamente...).
Super... ultra... mega... agradecido.
Pablo
pablgonz
Perlero nuevo
Perlero nuevo
 
Mensajes: 236
Registrado: 2010-09-08 21:03 @919
Ubicación: Concepción (Chile)

Añadir coma opcional en expresión regular

Notapor pablgonz » 2013-11-26 10:11 @466

Hola a todos. Tengo una modificación de un script que funciona bastante bien, pero agrega una coma extra que no es necesaria.

Los ficheros de entrada son de esta forma:
Sintáxis: [ Descargar ] [ Ocultar ]
  1. Primero (sin [...]) 
  2. \begin{PSTexample} 
  3. \includegraphics[scale=1.2]{archivo-fig-1} 
  4. \end{PSTexample} 
  5.  
  6. Segundo con [...] 
  7. \begin{example}[algo1=2,algo2=3,algo3=\?] 
  8. \includegraphics[scale=1]{archivo-fig-3} 
  9. \end{example} 
Con este script
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. use v5.16;
  3. use File::Basename;                       # dividir el archivo de entrada
  4. use autodie;                              # sale si tenemos un error
  5.  
  6. @ARGV == 0 && die "Ingresa un archivo\n";
  7.  
  8. my @SuffixList = (".tex","",".ltx");                    # extensión
  9. my ($name,$path,$ext) = fileparse($ARGV[0],@SuffixList);
  10. if ( $ext eq "" ) { $ext = ".tex"; }                    # fijamos la extensión
  11. my $TeXfile = "$path$name$ext";
  12. my $imageDir = "images";                                # directorio de imágenes (images por defecto)
  13. my $archivo_entrada = shift;
  14. my $archivo_salida  = "$name-tmp.tex";                  # archivo temp. de salida
  15.  
  16. ## Lectura del archivo
  17. open my $ENTRADA, '<', $archivo_entrada;
  18. my $archivo;
  19. {
  20.     local $/;
  21.     $archivo = <$ENTRADA>;
  22. }
  23. close   $ENTRADA;
  24.  
  25. ## Cambiamos
  26. $archivo =~
  27. s/(?<inicio>\\begin\{ .+? \})(?:\[)? (?<opciones>.*?):? (?:\])? \s+
  28. (?<graphics>(?<initpic>\\includegraphics)(?<scale>\[ .+? \])(\{)(?<picname>.+?) \})
  29. /$+{inicio}\[\\graphic=\{$+{scale}$imageDir\/$+{picname}\},$+{opciones}\]
  30. \\lstinputlisting[linerange=document-document]{$imageDir\/$+{picname}.tex}/gmx;
  31.  
  32. ## Guardamos en name-tmp.tex
  33. open my $SALIDA, '>', $archivo_salida;
  34. print $SALIDA $archivo;
  35. close $SALIDA;
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4

los modifico a esta forma:
Sintáxis: [ Descargar ] [ Ocultar ]
  1. Primero (sin [...]) 
  2. \begin{PSTexample}[\graphic={[scale=1.2]images/archivo-fig-1},] 
  3. \lstinputlisting[linerange=document-document]{images/archivo-fig-1.tex} 
  4. \end{PSTexample} 
  5.  
  6. Segundo con [...] 
  7. \begin{example}[\graphic={[scale=1]images/archivo-fig-3},algo1=2,algo2=3,algo3=\?] 
  8. \lstinputlisting[linerange=document-document]{images/archivo-fig-3.tex} 
  9. \end{example} 
y aquí es donde me sobra la "coma" en :
Sintáxis: [ Descargar ] [ Ocultar ]
  1. [\graphic={[scale=1.2]images/archivo-fig-1},] 

¿Cómo modifico la expresión regular para que, si está [...], añada la coma, y en caso contrario, no lo haga?

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

Re: Añadir coma opcional en expresión regular

Notapor explorer » 2013-11-26 13:46 @615

Creo que la solución está en convertir la segunda parte de la sustitución en una operación ejecutable, e insertar dentro de ella la comprobación de la definición de "opciones", o no, y poner la coma correspondiente:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. $archivo =~
  2. s/(?<inicio>\\begin\{ .+? \})(?:\[)? (?<opciones>.*?):? (?:\])? \s+
  3. (?<graphics>(?<initpic>\\includegraphics)(?<scale>\[ .+? \])(\{)(?<picname>.+?) \})
  4. /qq($+{inicio}\[\\graphic=\{$+{scale}$imageDir\/$+{picname}}) . ($+{opciones} ? "," : "") . qq($+{opciones}\]
  5. \\lstinputlisting\[linerange=document-document\]\{$imageDir\/$+{picname}.tex\})/gemx;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
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

AnteriorSiguiente

Volver a Básico

¿Quién está conectado?

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

cron