• Publicidad

Expresión regular: Cadena entre cadena

¿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: Cadena entre cadena

Notapor newperlero » 2011-08-23 06:12 @300

¡Hola!
Por una parte tengo un fichero con líneas tal que así:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
1999akestaesmicadenaak1212990as
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4

Quiero guardar en una variable lo que esté entre ak y ak.

El problema que tengo es que todo lo que haya por delante y por detrás es variable, pueden ser números, letras, caracteres, de 1 a n veces.

Quiero hacerlo con una expresión regular, sin usar split(), substr(), unpack() o similares.

¿Me podéis echar un cable?

No sé cómo decirle a la expresión regular "Cójeme lo que haya entre esto y esto" :?
newperlero
Perlero nuevo
Perlero nuevo
 
Mensajes: 42
Registrado: 2011-07-15 06:38 @318

Publicidad

Re: Expresión regular: Cadena entre cadena

Notapor explorer » 2011-08-23 06:23 @308

Prueba con esto:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. use 5.010;
  2. my $texto = '1999akestaesmicadenaak1212990as';
  3. while ($texto =~ m/ ak (.*?) ak /gsmx) {
  4.     say "[$1]";
  5. }
Coloreado en 0.003 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: Expresión regular: Cadena entre cadena

Notapor newperlero » 2011-08-23 06:55 @329

Funcionar, ¡funciona perfecto! Pero la verdad, no entiendo como funciona.

Por una parte, ¿qué indicas con (.*?)?

Y por otra, las opciones que le pasas a la expresión regular, no las veo claras:
* Por una parte /g, que significa que se hará global a todo el texto
* Por otra parte /s, que implica que solo mirará el string de una línea
* Pero por otra parte, está el /m, que según leo por ahí "Múltiples Líneas" (¿¿¿¿Aceptará strings de otras líneas???? ) ¿No se contradicen s y m?
* Y de /x tenía entendido que solo era para poder poner espacios en las regexp, pero si lo quito, no funciona...
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
    Extend your pattern's legibility by permitting whitespace and comments.

These are usually written as ``the /x modifier'', even though the delimiter in question might not actually be a slash. In fact, any of these modifiers may also be embedded within the regular expression itself using the new (?...) construct. See below.

The /x modifier itself needs a little more explanation. It tells the regular expression parser to ignore whitespace that is neither backslashed nor within a character class. You can use this to break up your regular expression into (slightly) more readable parts. The # character is also treated as a metacharacter introducing a comment, just as in ordinary Perl code. This also means that if you want real whitespace or # characters in the pattern (outside of a character class, where they are unaffected by /x), that you'll either have to escape them or encode them using octal or hex escapes. Taken together, these features go a long way towards making Perl's regular expressions more readable. Note that you have to be careful not to include the pattern delimiter in the comment--perl has no way of knowing you did not intend to close the pattern early. See the C-comment deletion code in the perlop manpage.
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4

He estado haciendo pruebas y el código funciona solo con /gx, /m y /s no son necesarios en mi caso.

¡¡¡Muchas gracias por tu tiempo, explorer!!!
newperlero
Perlero nuevo
Perlero nuevo
 
Mensajes: 42
Registrado: 2011-07-15 06:38 @318

Re: Expresión regular: Cadena entre cadena

Notapor explorer » 2011-08-23 08:43 @405

$texto =~ m/ ak (.*?) ak /gsmx quiere decir:
  • Por la presencia de /x, los espacios en blanco que hay entre los subpatrones, no se tienen en cuenta, así que podríamos reescribirlo como $texto =~ m/ak(.*?)ak/gsm, aunque queda un poco "apretado"
  • /g es para que repita la búsqueda a lo largo de todo el $texto
  • /s es para que trate a $texto como una sola línea. Esto es: hace que '.' también encuentre a los caracteres de fin de línea
  • /m indica que $texto se compone de varias líneas. Esto es: hace que '^' coincida con los comienzos de cada línea (y no solo el comienzo de $texto) y que '$' coincida con el final de cada línea (y no solo con el final del $texto)
  • /sm, juntos, es lo recomendado, desde hace unos años, pues así es más fácil de entender para la gente que empieza: quiere decir que los caracteres '.', '^' y '$' tienen su significado normal dentro de $texto. Si necesitáramos buscar coincidencia con el principio del $texto, usaríamos '\A', y con '\z' coincidiríamos con el final de $texto
  • (.*?) por la presencia de los paréntesis, estamos ante un grupo de captura. Lo que vamos a capturar es cualquier carácter (.) seguido por cero o más de ellos (*), pero hasta justo antes del próximo 'ak' (?)
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: Expresión regular: Cadena entre cadena

Notapor newperlero » 2011-08-24 02:48 @158

No solo me ayudas con las dudas, es que lo explicas todo a la perfección.
Gracias es poco.

¡¡Saludos!!
newperlero
Perlero nuevo
Perlero nuevo
 
Mensajes: 42
Registrado: 2011-07-15 06:38 @318


Volver a Básico

¿Quién está conectado?

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