• Publicidad

Expresión regular con saltos de línea y espacios

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

Expresión regular con saltos de línea y espacios

Notapor pablgonz » 2014-08-26 22:10 @965

Hola a todos en el foro, vuelvo por acá con el siguiente problema: Poseo el siguiente script con el cual leo, divido y modifico unas cuantas líneas de un fichero de texto, pero, ahora me he topado con una expresión regular con la cual no doy. Me explico: si el fichero de entrada es así (test.tex):
Sintáxis: [ Descargar ] [ Ocultar ]
Using latex Syntax Highlighting
  1. \documentclass[a4paper,11pt]{article}
  2. \usepackage[T1]{fontenc}
  3. \usepackage[utf8]{inputenc}
  4. \usepackage{lmodern}
  5. \usepackage[swpl]{pst-exa}
  6. \begin{document}
  7. No modificar
  8. \begin{PSTexample}[graphic={[scale=1]images/test-exa-1}]
  9. \psset{unit=0.5cm,runit=0.5cm}
  10. \begin{pspicture}[showgrid=true](0,3)(10,10)
  11. \psdot(2,4)
  12. \pscircle(7,7){2}
  13. \psCircleTangents(2,4)(7,7){2}
  14. \psdots(CircleT1)(CircleT2)
  15. %un comentario
  16. \end{pspicture}
  17. \end{PSTexample}
  18.  
  19. psset fuera ...
  20. \psset{
  21.        unit=0.5cm,%
  22.        runit=0.5cm
  23.        }
  24. \includegraphics[scale=1]{test-fig-1}
  25.  
  26. No modificar
  27. \begin{PSTexample}[graphic={[scale=1]images/test-exa-2}]
  28. \psset{unit=0.5cm,runit=0.5cm}%
  29. \begin{pspicture}[showgrid=true](0,3)(10,10)
  30. \psdot(2,4)
  31. \pscircle(7,7){2}
  32. \psCircleTangents(2,4)(7,7){2}
  33. \pcline[nodesep=-1cm,linecolor=blue](2,4)(CircleT1)
  34. \pcline[nodesep=-1cm,linecolor=blue](2,4)(CircleT2)
  35. \psdots(CircleT1)(CircleT2)
  36. %un comentario
  37. \uput[-80](Circle$T_1$){T1}
  38. \uput[115](Circle$T_2$){T2}
  39. \end{pspicture}
  40. \end{PSTexample}
  41.  
  42. Otro \psset{
  43. unit=0.5cm,runit=0.5cm
  44. }
  45. \includegraphics[scale=1]{test-fig-2}
  46.  
  47. y otro \psset{algo1=algo, algo2=12.325cm,runit=0.5cm}
  48. \includegraphics[scale=1]{test-fig-3} texto texto
  49.  
  50. \end{document}
  51.  
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4
deseo que el fichero de salida sea así:
Sintáxis: [ Descargar ] [ Ocultar ]
Using latex Syntax Highlighting
  1. \documentclass[a4paper,11pt]{article}
  2. \usepackage[T1]{fontenc}
  3. \usepackage[utf8]{inputenc}
  4. \usepackage{lmodern}
  5. \usepackage[swpl]{pst-exa}
  6. \begin{document}
  7. No modificar
  8. \begin{PSTexample}[graphic={[scale=1]images/test-exa-1}]
  9. \psset{unit=0.5cm,runit=0.5cm}
  10. \begin{pspicture}[showgrid=true](0,3)(10,10)
  11. \psdot(2,4)
  12. \pscircle(7,7){2}
  13. \psCircleTangents(2,4)(7,7){2}
  14. \psdots(CircleT1)(CircleT2)
  15. %un comentario
  16. \end{pspicture}
  17. \end{PSTexample}
  18.  
  19. psset fuera ...
  20. \includegraphics[scale=1]{test-fig-1}
  21.  
  22. No modificar
  23. \begin{PSTexample}[graphic={[scale=1]images/test-exa-2}]
  24. \psset{unit=0.5cm,runit=0.5cm}%
  25. \begin{pspicture}[showgrid=true](0,3)(10,10)
  26. \psdot(2,4)
  27. \pscircle(7,7){2}
  28. \psCircleTangents(2,4)(7,7){2}
  29. \pcline[nodesep=-1cm,linecolor=blue](2,4)(CircleT1)
  30. \pcline[nodesep=-1cm,linecolor=blue](2,4)(CircleT2)
  31. \psdots(CircleT1)(CircleT2)
  32. %un comentario
  33. \uput[-80](Circle$T_1$){T1}
  34. \uput[115](Circle$T_2$){T2}
  35. \end{pspicture}
  36. \end{PSTexample}
  37.  
  38. Otro
  39. \includegraphics[scale=1]{test-fig-2}
  40.  
  41. y otro
  42. \includegraphics[scale=1]{test-fig-3} texto texto
  43.  
  44. \end{document}
  45.  
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
es decir, deseo que busque todos las líneas de la forma
Sintáxis: [ Descargar ] [ Ocultar ]
  1. \psset{cualquier cosa incluidos saltos de linea y espacios}\n\includegraphics[scale=1]{nombrearchivoentrada-fig-número}} 
He intentado con el siguiente script:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. use v5.14.2;
  3. use re 'eval';
  4. use autodie;                                            # muere si ocurre un error
  5. use File::Basename;                                     # separa el archivo de entrada
  6.  
  7. ### Argumentos --------------------------------------------------------------
  8. @ARGV == 1  or die "Uso: $0 <archivo TeX a procesar>\n";
  9. my $nombre_archivo = shift;
  10. -f $nombre_archivo or die "ERROR: No encuentro [$nombre_archivo]\n";
  11.  
  12. ### Arreglo de la extensión -------------------------------------------------
  13. my @SuffixList = ('.tex', '', '.ltx');                  # posible extensión
  14. my ($name, $path, $ext) = fileparse($nombre_archivo, @SuffixList);
  15. $ext = '.tex' if not $ext;
  16.  
  17. ## Leer archivo (usar local)
  18. open my $INFILE, '<', "$name$ext";
  19. my $IPDF;
  20. {
  21.     local $/;
  22.     $IPDF = <$INFILE>;
  23. }
  24. close  $INFILE;
  25.  
  26. ## Constantes (escapamos)
  27. my $BEGINDOC = quotemeta('\begin{document}');
  28.  
  29. ## Dividir el archivo
  30. my($cabeza, $cuerpo) = $IPDF =~ m/\A (.+?) ($BEGINDOC .+?) \z/msx;
  31.  
  32. # Eliminación de psset y SpecialCoor en el preambulo
  33. $cabeza =~ s/ ^\\psset\{.+?\}/%\\psset delete by pst2pdf/gmsx;
  34. $cabeza =~ s/\\SpecialCoor/%\\SpecialCoor delete by pst2pdf/gmsx;
  35. $cabeza =~ s/ ^%CleanPST .+? %CleanPST/% Clean PST by pst2pdf/gmsx;
  36.  
  37. # Eliminación de psset sobrantes dentro del body (este regex falla por ahora)
  38. $cuerpo =~ s/ ^\\psset\{.+?\}\s*(\\includegraphics\[scale=1\]\{$name-fig-\d*\})/$1/gmsx;
  39.  
  40. print  $cuerpo;
  41.  
  42. ## Escribimos otro archivo
  43. open my $SALIDA, '>', "$name-out$ext";
  44. print   $SALIDA "$cabeza$cuerpo";
  45. close   $SALIDA;
  46. #
  47.  
Coloreado en 0.003 segundos, usando GeSHi 1.0.8.4
pero, esta expresión regular:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. $cuerpo =~ s/ ^\\psset\{.+?\}\s*(\\includegraphics\[scale=1\]\{$name-fig-\d*\})/$1/gmsx;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
no me corre.
Agradecido:
Pablo
pablgonz
Perlero nuevo
Perlero nuevo
 
Mensajes: 236
Registrado: 2010-09-08 21:03 @919
Ubicación: Concepción (Chile)

Publicidad

Re: Expresión regular con saltos de línea y espacios

Notapor explorer » 2014-08-26 23:50 @035

Hay un espacio en blanco delante de '^'.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14482
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Expresión regular con saltos de línea y espacios

Notapor pablgonz » 2014-08-27 06:15 @302

Gracias por la respuesta explorer, si quito el espacio en blanco tampoco caso lo que deseo.
pablgonz
Perlero nuevo
Perlero nuevo
 
Mensajes: 236
Registrado: 2010-09-08 21:03 @919
Ubicación: Concepción (Chile)

Re: Expresión regular con saltos de línea y espacios

Notapor explorer » 2014-08-27 19:39 @860

Con la siguiente exp. reg. me funciona, pero no sé muy bien por qué.

Sintáxis: [ Descargar ] [ Ocultar ]
  1. $cuerpo =~ s/\\psset\{[^\}]+\}(\s*\\includegraphics\[scale=1\]\{$name-fig-\d*\})/$1/gms; 
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14482
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Expresión regular con saltos de línea y espacios

Notapor pablgonz » 2014-08-28 11:23 @516

Muchas gracias, explorer, ahora funciona. Había intentado con algo parecido usando \s* pero me eliminaba partes que no deseaba.

Noto que no usas /x en la expresión regular, pero igual funciona. Al parecer las llaves en \psset{...} son las que causaban que la expresión regular que tenía ya no funcionara (estoy usando la versión 5.20).

Saludos.
PD: ¿Me podrías explicar las partes de \psset\{[^\}]+\}?
pablgonz
Perlero nuevo
Perlero nuevo
 
Mensajes: 236
Registrado: 2010-09-08 21:03 @919
Ubicación: Concepción (Chile)

Re: Expresión regular con saltos de línea y espacios

Notapor explorer » 2014-08-28 12:09 @548

No uso /x porque no uso patrones con espacios en blanco no significativos.

El problema estaba en que '\{.+?\}' capturaba demasiados caracteres (varias líneas) hasta que el patrón coincidía, con lo que la sustitución se realizaba con demasiados caracteres.

La solución fue modificar esa parte para que el motor de exp. reg. capturase solo caracteres que NO fueran llaves de cierre, entre llaves de cierre: '\{[^\}]+\}'. En la clase de caracteres ponemos una llave de cierre, pero negada (^), por lo que estamos diciendo "cualquier carácter que no sea una llave de cierre", que no es lo mismo que el patrón anterior que significaba "el menor número de caracteres antes de una llave de cierre". Era claro que en esa frase viene implícito el caso de que pueden haber llaves de cierre con tal de que se cumpla todo el patrón de la expresión regular: si el motor encuentra la primera llave de cierre, pero luego no cumple el resto del patrón, reanuda (backtracking) la búsqueda desde ese punto de otra llave de cierre.

En situaciones normales, el patrón '.+?' debería ser más que suficiente, pero estamos en un caso el que el texto tiene varias líneas, y que éstas pueden contener el patrón que buscamos, varias veces. Así que entonces es mejor ajustar aún más la búsqueda.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14482
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Expresión regular con saltos de línea y espacios

Notapor pablgonz » 2014-08-28 12:58 @582

Excelente, ahora me queda clara la expresión regular. Habitualmente usaba .+?, pero, como tú dices, en este caso no funcionaba.
pablgonz
Perlero nuevo
Perlero nuevo
 
Mensajes: 236
Registrado: 2010-09-08 21:03 @919
Ubicación: Concepción (Chile)


Volver a Básico

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 1 invitado

cron