web-dev-qa-db-fra.com

Comment écrire une instruction Ruby switch (cas ... quand) avec regex et backreferences?

Je sais que je peux écrire une instruction Ruby case pour vérifier une correspondance avec une expression régulière. Cependant, j'aimerais utiliser les données de correspondance dans ma déclaration de retour. Quelque chose comme ce semi-pseudocode :

foo = "10/10/2011"

case foo
    when /^([0-9][0-9])/
        print "the month is #{match[1]}"
    else
        print "something else"
end

Comment puis-je y parvenir?

Merci!


Juste une note: je comprends que je n'utiliserais jamais une instruction switch pour un cas simple comme ci-dessus, mais ce n'est qu'un exemple. En réalité, ce que j'essaie de réaliser est la correspondance de nombreuses expressions régulières potentielles pour une date qui peut être écrite de différentes manières, puis en l'analysant avec la classe Date de Ruby en conséquence.

79
Yuval Karmi

Les références aux derniers groupes de correspondance d'expressions régulières sont toujours stockées dans pseudo-variables$1 à $9:

case foo
when /^([0-9][0-9])/
    print "the month is #{$1}"
else
    print "something else"
end

Vous pouvez également utiliser le $LAST_MATCH_INFO pseudo variable pour obtenir l'ensemble de l'objet MatchData. Cela peut être utile lors de l'utilisation de captures nommées:

case foo
when /^(?<number>[0-9][0-9])/
    print "the month is #{$LAST_MATCH_INFO['number']}"
else
    print "something else"
end
145
Yossi

Voici une approche alternative qui vous donne le même résultat mais n'utilise pas de commutateur. Si vous placez vos expressions régulières dans un tableau, vous pouvez faire quelque chose comme ceci:

res = [ /pat1/, /pat2/, ... ]
m   = nil
res.find { |re| m = foo.match(re) }
# Do what you will with `m` now.

Déclarer m en dehors du bloc lui permet d'être toujours disponible après find est fait avec le bloc et find sera arrêtez dès que le bloc renvoie une valeur vraie afin que vous obteniez le même comportement de raccourci qu'un commutateur vous donne. Cela vous donne la pleine MatchData si vous en avez besoin (peut-être que vous voulez utiliser des groupes de capture nommés dans vos expressions régulières) et sépare bien vos expressions régulières de votre logique de recherche (qui peut ou non donne un code plus clair), vous pouvez même charger vos regex à partir d'un fichier de configuration ou choisir l'ensemble d'entre eux que vous vouliez au moment de l'exécution.

6
mu is too short