Estrai una sottostringa da una stringa in Ruby usando un'espressione regolare


130

Come posso estrarre una sottostringa all'interno di una stringa in Ruby?

Esempio:

String1 = "<name> <substring>"

Voglio estrarre substringda String1(cioè tutto nell'ultima occorrenza di <e >).

Risposte:


134
String1.scan(/<([^>]*)>/).last.first

scancrea una matrice che, per ciascuna <item>in, String1contiene il testo tra la <e la >in una matrice a un elemento (perché se usata con una regex contenente gruppi di acquisizione, la scansione crea una matrice contenente le acquisizioni per ogni corrispondenza). lastti dà l'ultimo di quegli array e firstpoi ti dà la stringa in esso.


319
"<name> <substring>"[/.*<([^>]*)/,1]
=> "substring"

Non c'è bisogno di usare scan, se abbiamo bisogno di un solo risultato.
Non c'è bisogno di usare Python match, quando abbiamo Ruby String[regexp,#].

Vedere: http://ruby-doc.org/core/String.html#method-i-5B-5D

Nota: str[regexp, capture] → new_str or nil


37
Non c'è bisogno di screditare altre soluzioni perfettamente valide (e potrei opine, più leggibili).
coreyward

41
@coreyward, se sono migliori, per favore, discutilo. Ad esempio, la soluzione di sepp2k è più flessibile ed è per questo che ho indicato la if we need only one resultmia soluzione. Ed match()[]è più lento, perché sono due metodi anziché uno.
Nakilon,

4
Questo è il più veloce di tutti i metodi presentati, ma anche il metodo più lento richiede solo 4,5 microsecondi sulla mia macchina. Non mi interessa speculare sul perché questo metodo sia più veloce. In termini di prestazioni, la speculazione è inutile . Conta solo la misurazione.
Wayne Conrad,

8
Trovo questa soluzione più semplice e precisa (dato che sono nuovo di Ruby). Grazie.
Ryan H.

@Nakilon La leggibilità può superare le minuscole differenze di prestazioni quando si considera il successo complessivo di un prodotto e di un team, quindi coreyward ha fatto un commento valido. Detto questo, penso che string[regex]possa essere altrettanto leggibile in questo scenario, quindi è quello che ho usato personalmente.
Nick,

24

Puoi usare un'espressione regolare abbastanza facilmente ...

Consentire spazi attorno alla parola (ma non tenerli):

str.match(/< ?([^>]+) ?>\Z/)[1]

O senza gli spazi consentiti:

str.match(/<([^>]+)>\Z/)[1]

1
Non sono sicuro che l'ultimo <>debba effettivamente essere l'ultima cosa nella stringa. Se ad esempio la stringa foo <bar> bazè consentita (e si suppone che dia il risultato bar), ciò non funzionerà.
sepp2k,

Sono appena andato in base alla stringa di esempio che ha fornito.
coreyward

10

Ecco un approccio leggermente più flessibile usando il matchmetodo. Con questo, puoi estrarre più di una stringa:

s = "<ants> <pants>"
matchdata = s.match(/<([^>]*)> <([^>]*)>/)

# Use 'captures' to get an array of the captures
matchdata.captures   # ["ants","pants"]

# Or use raw indices
matchdata[0]   # whole regex match: "<ants> <pants>"
matchdata[1]   # first capture: "ants"
matchdata[2]   # second capture: "pants"

3

Una scansione più semplice sarebbe:

String1.scan(/<(\S+)>/).last
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.