• 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 » 2014-03-24 13:35 @608

Dando vueltas y vueltas al problema, me percato de lo siguiente. Las líneas entre la cuales deseo buscar tienen más menos ésta forma:
Sintáxis: [ Descargar ] [ Ocultar ]
Using latex Syntax Highlighting
  1. \begin{$ENTORNO}{}[]
  2. ...
  3. \end{$ENTORNO}
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Donde $ENTORNO es igual a:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. my $ENTORNO  = qr/(v|V)erbatim(\*) | sperbatim(\*)| LTXexample | tcblisting | mybox | otras/x;
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4

Visto esto los casos que se pueden dar son 5:
Sintáxis: [ Descargar ] [ Ocultar ]
Using latex Syntax Highlighting
  1. \begin{$ENTORNO}[A]{B} salto de línea
  2. palabras que deseo cambiar usando el hash.
  3. \end{$ENTORNO}
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4
o así:
Sintáxis: [ Descargar ] [ Ocultar ]
Using latex Syntax Highlighting
  1. \begin{$ENTORNO}[A]salto de línea
  2. palabras que deseo cambiar usando el hash.
  3. \end{$ENTORNO}
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4
o así:
Sintáxis: [ Descargar ] [ Ocultar ]
Using latex Syntax Highlighting
  1. \begin{$ENTORNO}{B} salto de línea
  2. palabras que deseo cambiar usando el hash.
  3. \end{$ENTORNO}
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4
o así:
Sintáxis: [ Descargar ] [ Ocultar ]
Using latex Syntax Highlighting
  1. \begin{$ENTORNO}{B}[A] salto de línea
  2. palabras que deseo cambiar usando el hash.
  3. \end{$ENTORNO}
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4
o así:
Sintáxis: [ Descargar ] [ Ocultar ]
Using latex Syntax Highlighting
  1. \begin{$ENTORNO}salto de línea
  2. palabras que deseo cambiar usando el hash.
  3. \end{$ENTORNO}
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4
Donde A y B pueden contener saltos de línea, espacios, incluso parejas de [] y {}. Además pueden o no estar presentes, conmutando su posición [A]{B}, {B}[A], [A], {B}. Lo constante es que el inicio de lo que busco termina con un \s y que la palabra de cierre (\end{$ENTORNO}) es la misma con la que inicia la cadena sobre la cual deseo hacer los cambios. Creo que es demasiado complejo lo que busco o quizás se deba hacer de otra forma y no dentro del bucle, no estoy seguro.

Saludos,
Pablo
Última edición por explorer el 2014-03-24 14:43 @655, editado 1 vez en total
Razón: linea => línea
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 pablgonz » 2014-03-27 20:13 @884

Revisando el hilo, creo que entendí algo de forma errada, cuando me refería a que «no se anidan los entornos» sobre los cuales deseo buscar. Me refería a que las palabras que delimitan el texto (entornos) sobre el cual deseo los cambios no se repiten dentro de él, pero, sí pueden aparecer el resto de las palabras delimitadoras dentro de él.

Por ejemplo, si el entorno comienza por \begin{LTXexample} debe terminar en \end{LTXexample} y ninguna de estas dos palabras se repetirá dentro de este entorno (no se anidan) pero, sí pueden aparecer las demás, es decir, si las palabras que delimita son:
Sintáxis: [ Descargar ] [ Ocultar ]
  1. LTXexample | verbatim | verbatim*| Verbatim| Verbatim*| otras 
los entornos podrían ser:
Sintáxis: [ Descargar ] [ Ocultar ]
Using latex Syntax Highlighting
  1. \begin{LTXexample}
  2. \begin{verbatim}
  3. Palabras que deseo cambiar
  4. \end{verbatim}
  5. \end{LTXexample}
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4
o
Sintáxis: [ Descargar ] [ Ocultar ]
Using latex Syntax Highlighting
  1. \begin{LTXexample}
  2. \begin{Verbatim}
  3. Palabras que deseo cambiar
  4. \end{LTXexample}
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4
de manera más clara:
Sintáxis: [ Descargar ] [ Ocultar ]
Using latex Syntax Highlighting
  1. \begin{Palabra inicio}
  2. \begin{Palabra distinta a la de inicio} (puede estar o no presente)
  3. Palabras que deseo cambiar
  4. \end{Palabra distinta a la de inicio} (puede estar o no presente)
  5. \end{Palabra inicio}
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4
y el caso:
Sintáxis: [ Descargar ] [ Ocultar ]
Using latex Syntax Highlighting
  1. \begin{Palabra inicio}
  2. \begin{Palabra inicio} (Nunca estará presente)
  3. Palabras que deseo cambiar
  4. \end{Palabra inicio} (Nunca estará  presente)
  5. \end{Palabra inicio}
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4
no se puede dar.
Con esto el problema se me complica al doble, tengo un enredo de «Análisis combinatorio» entre [A]{B} y las palabras delimitadoras. Sé que el motor de expresiones regulares trabaja usando análisis combinatorio para cazar las búsquedas en la expresiones regulares, pero, no doy con la expresión regular que me permita hacer esto.

En fin, seguiré leyendo a ver si se me ocurre algo.
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 » 2014-03-29 15:38 @693

Viendo los cinco casos, el mínimo común denominador es...

/^\\begin\{($ENTORNO)\}/ .. /^\\end\{$1\}/

entonces, una solución es la de procesarlo por líneas:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. use v5.14.2;
  3. use File::Slurp;
  4.  
  5. my @lineas = read_file('code_36930_1.tex');
  6.  
  7. my %cambios = (
  8.     '\pspicture'                => '\TRICKS',
  9.     '\endpspicture'             => '\ENDTRICKS',
  10.  
  11.     '\begin{MYexample'          => '\begin{MYEXAMPLE',
  12.     '\end{MYexample'            => '\end{MYEXAMPLE',
  13.  
  14.     '\begin{pspicture'          => '\begin{TRICKS',
  15.     '\end{pspicture'            => '\end{TRICKS',
  16.  
  17.     '\begin{postscript}'        => '\begin{POSTRICKS}',
  18.     '\end{postscript}'          => '\end{POSTRICKS}',
  19. );
  20.  
  21. my $ENTORNO  = qr/(?: verbatim\*? | sperbatim\* | LTXexample | tcblisting | mybox | otras )/xi;
  22.    
  23. my $del;
  24.  
  25. for (@lineas) {
  26.     if (/^\\begin\{($ENTORNO)(?{ $del = "\Q$^N" })\}/ .. /^\\end\{$del\}/) {
  27.         while (my($busco, $cambio) = each %cambios) {
  28.             s/\Q$busco\E/$cambio/g;
  29.         }
  30.     }
  31.     print;
  32. }
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Este programa genera una salida casi a la que pides (le falta la parte de los \verb y alguna cosa más) pero es suficiente para que veas la idea: buscamos rangos completos no anidados, y aplicamos los cambios línea a línea.
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 » 2014-03-30 23:01 @001

Gracias explorer, pero, no puedo correrlo, me arroja el error:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. Eval-group not allowed at runtime, use re 'eval' in regex ..........
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
en la línea 26 y no lo he podido solucionar.

Entiendo cuál es la idea y el uso de .. para definir el rango (que es lo que buscaba). Creo que podré adaptar este esqueleto a lo que deseo; y otra consulta: ¿Puedo hacerlo sin el módulo File-Slurp? En el trabajo dispongo de Perl 5.16 pero solo con los módulos que vienen instalados por defecto (core, creo que es la palabra para esto).

Agradecido,
Pablo.

P.D.: Me he percatado que en varias de las últimas respuestas que has dado en el foro has usado éste módulo, ¿es mejor que usar Tie-File que viene instalado por defecto?
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 » 2014-03-31 05:40 @277

El aviso que te sale es porque tendrás activado el modo estricto, o quizás, los warnings, o tendrás un parámetro '-T' en la cabecera o en la llamada al programa.

Para solventarlo, tienes que hacer lo que te dice: coloca

use re 'eval';

al principio del programa.

El uso del operador rango viene bien cuando lo que queremos procesar son líneas. Esta forma de trabajo es idéntica -o hace lo mismo- que las soluciones anteriores en las que leíamos todo el archivo en una sola variable escalar, y aplicáramos la siguiente exp. reg.:

while ($cuerpo =~ /^\\begin\{($ENTORNO)\}(.+?)^\\end\{\1\}/g) {

y dentro del while tendríamos que hacer todo lo de las sustituciones de %cambios, y acordarnos de hacer un pos(), al final, para reposicionar la siguiente búsqueda en $cuerpo.

Solo que, como ves, no tenemos que reposicionar, ya que los cambios y la detección las hacemos por líneas enteras que imprimimos inmediatamente.

En cuanto al módulo File::Slurp, naturalmente que lo puedes hacer sin él. Yo he hecho lo siguiente: siendo el root del sistema, he ejecutado (en un sistema Linux Mint, donde estoy ahora)

apt-get install libfile-slurp-perl

Al cabo de 10 segundos, ya estaba instalado.

En el código, ya ves en qué consiste: la línea
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. my @lineas = read_file('code_36930_1.tex');
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

equivale a tener que escribir
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. my @lineas;
  2. {
  3.     open my $FILE, 'code_36930_1.tex';
  4.     @lineas = <$FILE>;
  5.     close $FILE;
  6. }
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
solo que, más cómodo :)
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 » 2014-03-31 13:49 @617

Genial, recordé que en Perl 5.16 el modo estricto viene activado por defecto, bastaba con agregar la línea que me comentaste y ya todo funciona a la perfección.

Un par de consultas para cerrar este hilo:
  • Un hash es conmutativo, es decir:
    Sintáxis: [ Descargar ] [ Ocultar ]
    Using perl Syntax Highlighting
    1. '\pspicture'   => '\TRICKS',
    Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
    es equivalente a:
    Sintáxis: [ Descargar ] [ Ocultar ]
    Using perl Syntax Highlighting
    1. '\TRICKS'    => '\pspicture',
    Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
    y de ser así , ¿cómo lo uso en este sentido?
  • Trabajar el archivo línea a línea, ¿es más rápido que usando las soluciones anteriores?
  • ¿Cuál es la diferencia entre .. y ...?
Bueno, eso sería todo por ahora, dividiré lo que deseo hacer en dos partes; una para \verb y otra para los entornos usando el mismo hash.

Agradecido por todo,
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 » 2014-03-31 14:47 @657

1. No. Un hash no es conmutativo. Un hash es un conjunto de pares clave/valor. Si quieres la versión contrario, debes crear nuevos pares claves/valor.

2. Depende. Lo normal es decir que, es mucho más rápido leer todo el archivo a memoria, y así reducimos el número de operaciones, a costa de complicarnos lo de buscar la información dentro de lo que hemos leído. Pero en otra ocasiones no nos quedará más remedio (caso de que el archivo sea muy grande y no entre en memoria). O que solo nos interesa procesar unas determinadas líneas.

3. La información sobre el operador rango la tienes en perldoc perlop:
En contexto de escalar, ".." devuelve un valor booleano. El operador es biestable, como un flip-flop, y emula el operador rango-de-línea de sed, awk, y diversos editores. Cada operador ".." mantiene su estado booleano propio, incluso a través de llamadas a la subrutina que lo contenga. Es falso, siempre y cuando su operando izquierdo sea falso. Una vez que el operando izquierdo sea verdadero, el operador rango se mantiene así hasta que el operando de la derecha sea verdadero, DESPUÉS de lo cual, el operador rango se vuelve falso de nuevo. No se vuelve falso hasta la próxima vez que el operador rango es evaluado. El operador rango puede probar el operando de la derecha y convertirse en falso en la misma evaluación en que se hizo verdadero (como en awk), pero aún así devuelve verdadero al menos una vez. Si no quiere poner a prueba el operando derecho hasta la próxima evaluación, al igual que en sed, solo tiene que utilizar tres puntos ("...") en lugar de dos. En todos los demás aspectos, "..." se comporta como "..".
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 » 2014-03-31 21:08 @922

Muchas gracias por la explicación, ahora me queda claro lo del hash y el operador de rango (algo me acordaba de sed). ¿Me puedes explicar cómo funciona (?<!patrón)? Traté de añadirlo para que no me procesara las líneas que iniciaban con uno o más signos de '%', pero no capto lo de ancho fijo de la documentación.

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 » 2014-04-01 04:53 @245

Lo de "ancho fijo" se refiere a que no puedes usar cuantificadores ('*', '+', '?', '{}').

Entonces, (?<!...) delimita un patrón "fijo" que no debe ocurrir antes de ese lugar del patrón principal.
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 » 2014-04-01 12:26 @560

Ok, entiendo, eso quiere decir que no me servirá para hacer lo que deseo. Mi idea era no procesar las líneas que comenzaran con uno o más '%', es decir, líneas de este estilo:
Sintáxis: [ Descargar ] [ Ocultar ]
Using latex Syntax Highlighting
  1. %\begin{LTXexample}
  2. ...
  3. %\end{LTXexample]
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4
o
Sintáxis: [ Descargar ] [ Ocultar ]
Using latex Syntax Highlighting
  1. %%% \begin{LTXexample}
  2. ...
  3. %%% \end{LTXexample]
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4
No deseo que las tome en cuenta. Quizás pueda añadir estas palabras al hash que uso en \verb que sí puede cambiar estos casos y luego crear un nuevo hash para modificar las palabras que deseo.

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

AnteriorSiguiente

Volver a Básico

¿Quién está conectado?

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