2009-05-22 15 views
11

Estoy tratando de analizar una cadena de varias líneas y obtener el resto de la línea siguiendo un patrón.¿Cuál es la "manera ruby" de analizar una cadena para una sola clave/valor?

texto:

 
hello john 
your username is: jj 
thanks for signing up 

Quiero extraer jj, alias todo después de "su nombre de usuario es:"

Una manera:

text = "hello john\nyour username is: jj\nthanks for signing up\n" 
match = text[/your username is: (.*)/] 
value = $1 

Pero esto me recuerda a Perl .. .y no "lee" tan naturalmente como me han dicho que ruby ​​debería.

¿Hay una manera más limpia? AKA ¿Una forma de "ruby"?

Gracias

+1

Ruby en realidad estaba bastante inspirado en Perl; se suponía que encajaba en el mismo nicho que Perl, pero con un buen sistema de objetos y una sintaxis más limpia y regular. En realidad tiene una serie de características tomadas directamente de Perl, como ruby ​​-p -i-e, aunque algunas de las características más similares a Perl están en desuso ahora. –

Respuesta

22

Su código es más o menos la forma en Ruby. Si no desea utilizar el mundial $1, puede utilizar la versión 2 arg String#[]:

match = text[/your username is: (.*)/, 1] 
+0

Gracias. ¡Eso es exactamente lo que estaba buscando! Retirar el dólar global parecía una escuela demasiado vieja. Fui y leí los documentos API para Ruby, Class: String y allí estaba. http://www.ruby-doc.org/core/classes/String.html#M000786 – SWR

6

El dividieron comando es útil mindbogglingly. Divide una cadena en una matriz de subcadenas, separando en lo que sea que pase. Si no le da ningún argumento, se divide en espacios en blanco. Así que si conoce la palabra que está buscando es el quinto "palabra" (división en ambos espacios y el carácter de retorno), se puede hacer esto:

text = "Hola John \ nel nombre de usuario es: jj \ nGracias por inscribirse \ n"
partido text.split = [5]

..pero tal vez eso no es lo suficientemente auto-documentado, o si desea permitir partidos de varias palabras. Usted puede hacer esto en su lugar:

línea media = text.split ("\ n") [1]
partido midline.split = ("nombre de usuario es:") .last

O tal de esta manera más concisa:

partido = texto [/ nombre de usuario es: (. *) /, 1]

+0

haría eso, pero dividir en "" en lugar de "su nombre de usuario es:" –

+1

+1 para un uso interesante de división para obtener la quinta palabra, no me había dado cuenta. –

+2

Wow, gracias por las múltiples rutas de ataque.;) No había notado la posibilidad de división, pero el texto entrante no es estático (el ejemplo fue muy simplificado) por lo que no funcionará ... pero fue una buena forma de atacar el problema. – SWR

4

No estoy seguro de si es más Ruby'ish, pero otra opción:

>> text = "hello john\nyour username is: jj\nthanks for signing up\n" 
>> text.match(/your username is: (.*)/)[1] 
=> "jj" 
+2

Así es como lo haría. No es técnicamente superior a la solución [], pero creo que la intención es más clara cuando lo estás rozando. – Chuck

3

Hay también Regexp#match, que devuelve un objeto MatchData, que tiene toda la información que pueda desear.

irb> match = /your username is: (.*)/.match "hello john\nyour username is: jj\nthanks for signing up\n" 
#=> #<MatchData:0x557f94> 
irb> match.pre_match 
#=> "hello john\n" 
irb> match.post_match 
#=> "\nthanks for signing up\n" 
irb> match[0] 
#=> "your username is: jj" 
irb> match[1] 
#=> "jj" 
Cuestiones relacionadas