2009-03-13 16 views
33

Un amigo me preguntó esto y me quedé perplejo: ¿hay alguna manera de crear una expresión regular que coincida con una secuencia del mismo personaje? Por ejemplo, coincida con 'aaa', 'bbb', pero no con 'abc'?¿Qué expresiones regulares pueden coincidir con secuencias del mismo personaje?

m|\w{2,3}| 

No sería el truco, ya que coincidiría con 'abc'.

m|a{2,3}| 

no resolvería el problema, ya que no coincidiría 'BBB', 'CCC', etc.

Respuesta

64

Claro ¡cosa! Agrupación y las referencias son sus amigos:

(.)\1+ 

Se coincidir 2 o más ocurrencias del mismo carácter. Por palabra caracteres constituyentes solamente, utilizan \w en lugar de ., es decir .:

(\w)\1+ 
+0

Esto solo coincidirá con algunos caracteres y fallará con '###'. Los ejemplos que dio fueron caracteres alfabéticos, pero en realidad no pide solo caracteres alfabéticos. Reemplazaría '\ w' con '.'. – gpojd

+0

Bueno, sobre la base de los ejemplos no operativos que el interrogador dio, supuse que deseaba hacer coincidir los caracteres alfabéticos solamente. Sin embargo, debería haber expresado esto en la explicación. –

+0

¿Qué significa la barra oblicua 1? – CodyBugstein

0

responder a mi propia pregunta, pero lo consiguió:

m|(\w)\1+| 
+0

\ W es lo contrario de lo que quieres, ¿no? – Telemachus

+0

Telemachus tiene razón, esto no coincidirá con los ejemplos que dio en la pregunta. – gpojd

+0

También es mejor no usar pipes (u otros delimitadores no predeterminados) para la expresión regular a menos que tenga una razón para hacerlo. – Pat

1

Esto es lo referencias hacia atrás son para.

m/(\w)\1\1/ 

harán el truco.

+1

Esto no coincidiría con 'aa'. – gpojd

3

Esto corresponderá con más de \ w haría, como @@@:

/(.)\1+/ 
+0

Este es el correcto, para "una secuencia del mismo personaje", y no solo los ejemplos "aaa", "bbb". +1 – Axeman

+0

¿Cuál es la diferencia entre incrustar la expresión dentro de barras inclinadas "/" y no usarlas? – skan

10

Tenga en cuenta que en Perl 5.10 tenemos notaciones alternativas de referencias hacia atrás también.

foreach (qw(aaa bbb abc)) { 
    say; 
    say ' original' if /(\w)\1+/; 
    say ' new way' if /(\w)\g{1}+/; 
    say ' relative' if /(\w)\g{-1}+/; 
    say ' named' if /(?'char'\w)\g{char}+/; 
    say ' named' if /(?<char>\w)\k<char>+/; 
} 
+0

http://perldoc.perl.org/perlre.html o http://perldoc.perl.org/search.html?q=perlre –

1

Esto también es posible el uso de expresiones regulares puros (es decir, las que describen los lenguajes regulares - no Perl expresiones regulares). Desafortunadamente, significa una expresión regular cuya longitud es proporcional al tamaño del alfabeto, por ejemplo .:

(a* + b* + ... + z*) 

Donde a ... z son los símbolos en el alfabeto finito.

¡Así que las expresiones regulares de Perl, aunque son un superconjunto de expresiones regulares puras, definitivamente tienen sus ventajas incluso cuando solo quieres usarlas para expresiones regulares puras!

Cuestiones relacionadas