2009-02-06 20 views
75

Sto cercando un modo per eseguire una corrispondenza regolare su una stringa in Ruby e farla cortocircuitare nella prima partita.Restituisce la prima corrispondenza di Ruby regex

La stringa che sto elaborando è lunga e da quello che sembra il modo standard (metodo match) elaborerebbe il tutto, raccogliere ogni corrispondenza e restituire un oggetto MatchData che contiene tutte le corrispondenze.

match = string.match(/regex/)[0].to_s 

risposta

106

Si potrebbe provare variableName[/regular expression/]. Questo è un esempio di output da IRB:

irb(main):003:0> names = "erik kalle johan anders erik kalle johan anders" 
=> "erik kalle johan anders erik kalle johan anders" 
irb(main):004:0> names[/kalle/] 
=> "kalle" 
+0

Non sta facendo una corrispondenza e restituendo il primo risultato dietro le quinte? – Gishu

+5

Dopo alcuni benchmark con varie stringhe di lunghezza e guardando la sorgente C, si scopre che Regex.match fa corto circuito e trova solo la prima corrispondenza. –

+2

Neat, non sapeva di questa scorciatoia. – Pierre

19

Se solo l'esistenza di una partita è importante, si può andare con

/regexp/ =~ "string" 

In entrambi i casi, match deve restituire solo il primo colpo, mentre scan ricerche per tutta la stringa. Pertanto se

matchData = "string string".match(/string/) 
matchData[0] # => "string" 
matchData[1] # => nil - it's the first capture group not a second match 
1

Un'espressione regolare (regex) non è altro che una macchina a stati finiti (FSM).

Un FSM tenta di rispondere alla domanda "È possibile o no questo stato?"

Continua a tentare di creare una corrispondenza di modello finché non viene trovata una corrispondenza (esito positivo) o finché non vengono esplorati tutti i percorsi e non è stata trovata alcuna corrispondenza (errore).

In caso di successo, la domanda "È possibile o no questo stato?" è stato risposto con un "sì". Quindi non è necessario un ulteriore abbinamento e la regex ritorna.

Vedere this e this per ulteriori informazioni.

Inoltre: here is an interesting example per dimostrare come funziona la regex. Qui, una regex viene utilizzata per rilevare se un numero dato è primo. Questo esempio è in perl, ma può anche essere scritto in ruby.

44

È possibile utilizzare []: (che è come match)

"[email protected]"[/\+([^@]+)/, 1] # matches what is inside() 
# => "account2" 
"[email protected]"[/\+([^@]+)/, 0] # matches whole regexp 
# => "+account2" 
+3

risposta completa migliore – akostadinov

1

Non sono ancora sicuro se questa funzione è impressionante o semplicemente totalmente pazzi, ma la vostra regex può definire variabili locali.

/\$(?<dollars>\d+)\.(?<cents>\d+)/ =~ "$3.67" #=> 0 
dollars #=> "3" 

(Tratto da http://ruby-doc.org/core-2.1.1/Regexp.html).

Problemi correlati