157 votes

Extraire une sous-chaîne d'une chaîne en Ruby à l'aide d'une expression régulière

Comment extraire une sous-chaîne à l'intérieur d'une chaîne de caractères en Ruby ?

Exemple :

String1 = "<name> <substring>"

Je veux extraire substring de String1 (c'est-à-dire tout ce qui se trouve dans la dernière occurrence de < et > ).

366voto

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

Pas besoin d'utiliser scan si nous n'avons besoin que d'un seul résultat.
Il n'est pas nécessaire d'utiliser l'outil Python match alors que nous avons l'outil de Ruby String[regexp,#] .

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

Note : str[regexp, capture] new_str or nil

41 votes

Il n'est pas nécessaire de discréditer d'autres solutions parfaitement valables (et, à mon avis, plus lisibles).

44 votes

@coreyward, si elles sont meilleures, s'il vous plaît, argumentez-les. Par exemple, la solution de sepp2k est plus flexible, et c'est pourquoi j'ai indiqué if we need only one result dans ma solution. Et match()[] est plus lent, car il s'agit de deux méthodes au lieu d'une.

6 votes

C'est la plus rapide de toutes les méthodes présentées, mais même la méthode la plus lente ne prend que 4,5 microsecondes sur ma machine. Je n'ai pas envie de spéculer sur la raison pour laquelle cette méthode est plus rapide. En matière de performances, la spéculation est inutile . Seule la mesure compte.

151voto

sepp2k Points 157757
String1.scan(/<([^>]*)>/).last.first

scan crée un tableau qui, pour chaque <item> sur String1 contient le texte entre les < et le > dans un tableau à un élément (car lorsqu'il est utilisé avec une regex contenant des groupes de capture, scan crée un tableau contenant les captures pour chaque correspondance). last vous donne le dernier de ces tableaux et first puis vous donne la chaîne qui s'y trouve.

26voto

coreyward Points 26109

Vous pouvez utiliser une expression régulière pour cela assez facilement

Autoriser les espaces autour du mot (mais ne pas les conserver) :

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

Ou sans les espaces autorisés :

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

1 votes

Je ne suis pas sûr que le dernier <> doit en fait être la dernière chose dans la chaîne. Si, par exemple, la chaîne foo <bar> baz est autorisé (et censé donner le résultat bar ), cela ne fonctionnera pas.

0 votes

Je me suis juste basé sur l'exemple de chaîne qu'il a fourni.

12voto

Grant Birchmeier Points 4023

Voici une approche un peu plus souple, qui utilise la fonction match méthode. Avec cette méthode, vous pouvez extraire plus d'une chaîne de caractères :

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"

7voto

Navid Points 41

Un scan plus simple serait :

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X