2009-05-22 19 views
11

Sto cercando di analizzare una stringa multi linea e ottenere il resto della linea seguendo uno schema.Qual è il "modo rubino" per analizzare una stringa per una singola chiave/valore?

testo:

 
hello john 
your username is: jj 
thanks for signing up 

Voglio estrarre jj, alias tutto dopo "il nome utente è:"

Un modo:

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

Ma questo mi ricorda perl .. e non "legge" con la stessa naturalezza che mi viene raccontata da Ruby.

C'è un modo più pulito? AKA Un modo "rubino"?

Grazie

+1

Ruby era in realtà abbastanza pesantemente ispirato da Perl; doveva essere inserito nella stessa nicchia del Perl, ma con un buon sistema di oggetti e sintassi più pulito e regolare. In realtà ha un numero di funzioni prese direttamente da Perl, come ruby ​​-p -i -e, anche se alcune delle caratteristiche più simili a Perl sono deprecate ora. –

risposta

22

il codice è più o meno il modo in cui Ruby. Se non si desidera utilizzare il globale $1, è possibile utilizzare la versione 2 arg String#[]:

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

Grazie. Questo è esattamente quello che stavo cercando! Tirare su dollari globali sembrava solo troppo vecchia scuola. Ho letto e letto i documenti API per Ruby, Class: String ed eccolo lì. http://www.ruby-doc.org/core/classes/String.html#M000786 – SWR

6

Il divisi comando è mindbogglingly utile. Divide una stringa in una serie di sottostringhe, separando ciò che si passa. Se non si assegna alcun argomento, si divide su spazi vuoti. Quindi, se si conosce la parola che stai cercando è il quinto "parola" (splitting su entrambi gli spazi e il carattere di ritorno), si può fare questo:

text = "ciao John \ nIl tuo username è: jj \ nGrazie per la firma \ n"
match = text.split [5]

..ma forse non è sufficientemente auto-documentazione, o si desidera consentire per le partite più parole. Si potrebbe fare questo, invece:

linea mediana = text.split ("\ n") [1]
match = midline.split ("username è:") .last

O forse in questo modo più laconico:

partita = text [/ username è: (. *) /, 1]

+0

lo farei, ma dividerei "" invece di "il tuo nome utente è:" –

+1

+1 per un uso interessante di split per ottenere la quinta parola, non l'avevo notato. –

+2

Wow, grazie per i molteplici percorsi di attacco.;) Non avevo notato la possibilità di dividere, ma il testo in arrivo non è statico (l'esempio è stato notevolmente semplificato) quindi non funzionerà ... ma è stato un bel modo per attaccare il problema. – SWR

4

Non so se è più Ruby'ish, ma un'altra opzione:

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

Ecco come lo farei. Non è tecnicamente superiore alla soluzione [], ma penso che l'intento sia più chiaro quando lo stai sfiorando. – Chuck

3

C'è anche Regexp#match, che restituisce un oggetto MatchData, che ha tutte le informazioni che si possono desiderare.

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" 
Problemi correlati