Correspondance du groupe Ruby Regexp, atsortingbuer des variables sur 1 ligne

Je suis en train d’essayer de repexer une chaîne en plusieurs variables. Exemple de chaîne:

ryan_ssortingng = "RyanOnRails: This is a test" 

Je l’ai associé à cette expression rationnelle, avec 3 groupes:

 ryan_group = ryan_ssortingng.scan(/(^.*)(:)(.*)/i) 

Maintenant, pour accéder à chaque groupe, je dois faire quelque chose comme ceci:

 ryan_group[0][0] (first group) RyanOnRails ryan_group[0][1] (second group) : ryan_group[0][2] (third group) This is a test 

Cela semble assez ridicule et on a l’impression de faire quelque chose de mal. Je m’attendrais à pouvoir faire quelque chose comme ça:

 g1, g2, g3 = ryan_ssortingng.scan(/(^.*)(:)(.*)/i) 

Est-ce possible? Ou existe-t-il une meilleure façon que je le fais?

Vous ne voulez pas scan pour cela, car cela n’a pas beaucoup de sens. Vous pouvez utiliser Ssortingng#match qui renverra un object MatchData , vous pourrez alors appeler #captures pour renvoyer un tableau de captures. Quelque chose comme ça:

 #!/usr/bin/env ruby ssortingng = "RyanOnRails: This is a test" one, two, three = ssortingng.match(/(^.*)(:)(.*)/i).captures p one #=> "RyanOnRails" p two #=> ":" p three #=> " This is a test" 

Sachez que si aucune correspondance n’est trouvée, la correspondance de Ssortingng#match renvoie zéro, donc quelque chose comme ça pourrait mieux fonctionner:

 if match = ssortingng.match(/(^.*)(:)(.*)/i) one, two, three = match.captures end 

Bien que le scan ait peu de sens pour cela. Il fait toujours le travail, il suffit juste d’aplatir le tableau retourné en premier. one, two, three = ssortingng.scan(/(^.*)(:)(.*)/i).flatten

Vous pouvez utiliser Match ou = ~ à la place, ce qui vous donnerait une seule correspondance et vous pouvez soit accéder aux données de la même manière ou simplement utiliser les variables de correspondance spéciales $ 1, $ 2, $ 3.

Quelque chose comme:

 if ryan_ssortingng =~ /(^.*)(:)(.*)/i first = $1 third = $3 end 

Vous pouvez nommer vos matchs capturés

 ssortingng = "RyanOnRails: This is a test" /(?^.*)(?:)(?.*)/i =~ ssortingng puts one, two, three 

Cela ne fonctionne pas si vous inversez l’ordre des chaînes et des regex.

Vous devez décider si c’est une bonne idée, mais ruby ​​regexp peut (automatiquement) définir des variables locales pour vous!

Je ne suis pas encore sûr que cette fonctionnalité soit géniale ou simplement complètement folle, mais votre regex peut définir des variables locales.

 ryan_ssortingng = "RyanOnRails: This is a test" /^(?.*)(?:)(?)/ =~ ryan_ssortingng^ # This defined three variables for you. Crazy, but true. webframework # => "RyanOnRails" puts "W: #{webframework} , C: #{colon}, R: #{rest}" 

(Consultez http://ruby-doc.org/core-2.1.1/Regexp.html , recherchez “variable locale”).

Remarque: Comme indiqué dans un commentaire, je constate qu’une réponse similaire et antérieure à @toonsend ( https://stackoverflow.com/a/21412455 ) a été apscope à cette question. Je ne pense pas que je “volais”, mais si vous voulez être juste avec des éloges et honorer la première réponse, sentez-vous libre 🙂 J’espère qu’aucun animal n’a été blessé.

scan() trouvera toutes les correspondances de regex qui ne se chevauchent pas dans votre chaîne. Ainsi, au lieu de renvoyer un tableau de vos groupes comme vous le souhaitez, il renvoie un tableau de tableaux.

Vous devriez probablement utiliser match() , puis obtenir le tableau de captures à l’aide des captures MatchData#captures :

 g1, g2, g3 = ryan_ssortingng.match(/(^.*)(:)(.*)/i).captures 

Cependant, vous pouvez aussi faire cela avec scan() si vous voulez:

 g1, g2, g3 = ryan_ssortingng.scan(/(^.*)(:)(.*)/i)[0]