2011-12-14 12 views
6

Tengo la cadena "111221" y quiero hacer coincidir todos los conjuntos de enteros iguales consecutivos: ["111", "22", "1"].Secuencias de coincidencia de caracteres consecutivos en una cadena

Sé que hay una cosa especial de expresiones regulares para hacer eso, pero no puedo recordarlo y soy terrible en Google.

+1

lo que debe suceder cuando la entrada tiene caracteres que no sean dígitos, por ejemplo, '" 111aaa222 "' y '" 111aaa111 "'? – Phrogz

Respuesta

10

El uso de expresiones regulares en Ruby 1.8.7+:

p s.scan(/((\d)\2*)/).map(&:first) 
#=> ["111", "22", "1"] 

Esto funciona porque (\d) capta cualquier dígito, y luego \2* captura cero o más de lo que ese grupo (el segundo paréntesis de apertura) haya igualado. El (…) externo es necesario para capturar la coincidencia completa como resultado en scan. Por último, scan solo devuelve:

[["111", "1"], ["22", "2"], ["1", "1"]] 

... así que tenemos que correr a través y mantener sólo el primer elemento de cada matriz. En Rubí 1.8.6+ (que no tiene Symbol#to_proc por conveniencia):

p s.scan(/((\d)\2*)/).map{ |x| x.first } 
#=> ["111", "22", "1"] 

Sin expresión regular, esto es una diversión (encaje cualquier char) que funciona en Ruby 1.9.2:

p s.chars.chunk{|c|c}.map{ |n,a| a.join } 
#=> ["111", "22", "1"] 

Aquí hay otra versión que debería funcionar incluso en Ruby 1.8.6:

p s.scan(/./).inject([]){|a,c| (a.last && a.last[0]==c[0] ? a.last : a)<<c; a } 
# => ["111", "22", "1"] 
+1

su "diversión uno" coincidiría con "00aa00" como ["000000"] - funciona en la entrada de muestra, pero no en ningún ejemplo no trivial. – klochner

+0

@klochner ¡Ack! Estás en lo correcto. Reparado, gracias. – Phrogz

-2

se puede probar es

string str ="111221"; 
string pattern [email protected]"(\d)(\1)+"; 

La esperanza puede ayudarle a

+1

Downvoted porque a) esto no funciona (necesita '*' en lugar de '+') yb) esta no es la sintaxis de Ruby, y no funciona en Ruby ni siquiera directamente. – Phrogz

Cuestiones relacionadas