Restituisce la prima corrispondenza dell'espressione regolare Ruby


97

Sto cercando un modo per eseguire una corrispondenza regex su una stringa in Ruby e metterla in cortocircuito alla prima corrispondenza.

La stringa che sto elaborando è lunga e da quello che sembra il modo standard ( matchmetodo) elaborerebbe l'intera cosa, raccoglierebbe ogni corrispondenza e restituirebbe un oggetto MatchData contenente tutte le corrispondenze.

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

Risposte:


134

Potresti 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"

Questo non è fare una partita e restituire il primo risultato dietro le quinte?
Gishu

7
Dopo un po 'di benchmarking con stringhe di varie lunghezze e guardando la sorgente C, risulta che Regex.match va in cortocircuito e trova solo la prima corrispondenza.
Daniel Beardsley,

3
Neat, non sapevo di questa scorciatoia.
Pierre

C'è della documentazione su questo collegamento? Ho cercato in alto e in basso quello che pensavo fosse un compito relativamente semplice e ho risolto il problema solo dopo averlo trovato. Grazie!
dmourati

5
@dmourati È possibile trovare questa funzionalità documentata in String # [] . Grazie per aver chiesto informazioni sul documento, perché leggendolo ho trovato l' captureargomento, che ti consente di restituire un'acquisizione invece della corrispondenza completa.
Slothbear

68

Puoi usare []: (che è come match)

"foo+account2@gmail.com"[/\+([^@]+)/, 1] # matches capture group 1, i.e. what is inside ()
# => "account2"
"foo+account2@gmail.com"[/\+([^@]+)/]    # matches capture group 0, i.e. the whole match
# => "+account2"

4
migliore risposta completa
akostadinov

23

Se solo l'esistenza di una partita è importante, puoi andare con

/regexp/ =~ "string"

In ogni matchcaso , dovrebbe restituire solo il primo risultato, mentre la scanricerca viene eseguita nell'intera stringa. Quindi se

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

8

Non sono ancora sicuro se questa funzione sia fantastica o semplicemente totalmente pazza, ma la tua 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 ).


Funzionalità fantastica! Proprio quello di cui avevo bisogno
RaphaMex

Avvertenza: funziona solo quando regex =~ string", not when string = ~ regex`
Christopher Oezbek

2

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

Un FSM tenta di rispondere alla domanda "Questo stato è possibile o no?"

Continua a tentare di creare una corrispondenza di pattern finché non viene trovata una corrispondenza (successo), o finché tutti i percorsi non vengono esplorati 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 sono necessarie ulteriori corrispondenze e la regex ritorna.

Vedi questo e questo per saperne di più su questo.

Inoltre: ecco un esempio interessante per dimostrare come funziona la regex. Qui, un'espressione regolare viene utilizzata per rilevare se un numero fornito è primo. Questo esempio è in perl, ma può anche essere scritto in ruby.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.