2010-11-06 20 views

Respuesta

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

scan crea una matriz que, para cada <item> en String1 contiene el texto entre el < y la > en una matriz de una elemento (porque cuando se utiliza con una expresión regular que contiene grupos de captura, exploración crea una matriz que contiene el capturas para cada partido). last le da la última de esas matrices y first le da la cadena.

13

Se puede utilizar una expresión regular para que con bastante facilidad ...

Permitir espacios alrededor de la palabra (pero no mantenerlos):

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

o sin los espacios permitidos:

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

No estoy seguro de que el último '<>' realidad tiene que ser la última cosa en la cuerda. Si, por ejemplo, la cadena 'foo baz' está permitida (y se supone que da el resultado' bar'), esto no funcionará. – sepp2k

+0

Acabo de ir en función de la cadena de muestra que proporcionó. – coreyward

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

No es necesario utilizar scan, si solo necesitamos un resultado.
No es necesario usar match, cuando tenemos String[regexp,#].

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

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

+24

No es necesario desacreditar a otras soluciones perfectamente válidas (y podría opinar, más legibles). – coreyward

+27

@coreyward, si son mejores, por favor, argumento. Por ejemplo, la solución de sepp2k es más flexible, y es por eso que señalé 'si solo necesitamos un resultado' en mi solución. Y 'match() []' es más lento, porque son dos métodos en lugar de uno. – Nakilon

+1

Estoy aquí para ayudar, no para discutir. Llamar a dos métodos * es * más lento, pero en una cantidad infinitesimal que tomaría cientos de millones de iteraciones para que tenga un efecto medible. No hay una única solución "correcta" para ningún problema. – coreyward

8

Aquí hay un enfoque un poco más flexible, utilizando el método match. Con esto, se puede extraer más de una cadena:

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

Una exploración más simple sería:

String1.scan(/<(\S+)>/).last 
Cuestiones relacionadas