¿Qué regex puede coincidir con las secuencias del mismo personaje?

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, unir en ‘aaa’, ‘bbb’, pero no ‘abc’?

m|\w{2,3}| 

No haría el truco, ya que coincidiría con ‘abc’.

 m|a{2,3}| 

No funcionaría, ya que no coincidiría con ‘bbb’, ‘ccc’, etc.

¡Cosa segura! Agrupación y referencias son tus amigos:

 (.)\1+ 

Emparejará 2 o más ocurrencias del mismo personaje. Para los caracteres de palabra solo, use \w lugar de . , es decir:

 (\w)\1+ 

Tenga en cuenta que en Perl 5.10 también tenemos anotaciones alternativas para las referencias retrospectivas.

 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 /(?\w)\k+/; } 

Esto coincidirá más que \ w , como @@@:

 /(.)\1+/ 

Esto es para lo que son las referencias.

 m/(\w)\1\1/ 

hará el truco

Esto también es posible usando expresiones regulares puras (es decir, aquellas que describen los lenguajes regulares, no las expresiones regulares de Perl). 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 Perl regexps, aunque un superconjunto de expresiones regulares puras, definitivamente tiene sus ventajas incluso cuando solo quieres usarlas para expresiones regulares puras!

Respondiendo mi propia pregunta, pero la obtuve:

 m|(\w)\1+| 

Si está utilizando Java, y encuentra caracteres duplicados en una cadena dada aquí está el código,

 public class Test { public static void main(String args[]) { String s = "abbc"; if (s.matches(".*([a-zA-Z])\\1+.*")) { System.out.println("Duplicate found!"); } else { System.out.println("Duplicate not found!"); } } 

}