Lorsque vous utilisez des expressions régulières dans Ruby, quelle est la différence entre $ 1 et \ 1?
Répondre
\ 1 est une référence arrière qui ne fonctionne que dans le même sub
ou gsub
appel de méthode, par exemple:
"foobar".sub(/foo(.*)/, '\1\1') # => "barbar"
1 $ est une variable globale qui peut être utilisé dans le code plus tard:
if "foobar" =~ /foo(.*)/ then
puts "The matching word was #{$1}"
end
Sortie:
"The matching word was bar"
# => nil
Gardez à l'esprit qu'il existe une troisième option, la b forme de verrouillage de sub
. Parfois vous en avez besoin. Supposons que vous souhaitiez remplacer du texte par l'inverse de ce texte. Vous ne pouvez pas utiliser 1 $ parce qu'il est pas lié assez rapidement:
"foobar".sub(/(.*)/, $1.reverse) # WRONG: either uses a PREVIOUS value of $1,
# or gives an error if $1 is unbound
Vous pouvez également ne pas utiliser \1
, parce que la méthode sub
fait juste un texte simple substitution de \1
avec le texte capturé approprié, il n'y a pas de magie qui se déroule ici:
"foobar".sub(/(.*)/, '\1'.reverse) # WRONG: returns '1\'
donc, si vous voulez faire quoi que ce soit de fantaisie, vous devez utiliser la forme de sub
bloc (1 $, 2 $, $ `, « etc. $ seront disponibles):
"foobar".sub(/.*/){|m| m.reverse} # => returns 'raboof'
"foobar".sub(/(...)(...)/){$1.reverse + $2.reverse} # => returns 'oofrab'
Votre exemple pourrait être trompeur - la correspondance est ce qui est passé au bloc, pas les groupes de correspondance. Donc, si vous vouliez changer "foobar" en "foorab", vous auriez à faire 'str.sub (/ (foo) (\ w +) /) {$ 1 + $ 2.reverse}' – rampion
Voir ri Chaîne # sub : Dans la forme de bloc, la chaîne de correspondance actuelle est transmise en tant que paramètre et les variables telles que $ 1, $ 2, $ ', $ & et $ 'seront définies de manière appropriée. La valeur renvoyée par le bloc sera substituée à la correspondance sur chaque appel. – rampion
À droite, je vais modifier pour l'effacer. –
Notez que [le traitement des guillemets simples et doubles par Ruby] (http://stackoverflow.com/a/3028799/303896) peut vous gêner lorsque vous essayez d'utiliser des références arrières. – alxndr
n'a pas beaucoup compris, quelqu'un peut-il fournir plus d'explications? – YasirAzgar
@YasirAzgar '.sub()' est un appel de méthode. ''\'' ne peut (apparemment) être utilisé que dans le cadre d'un appel de méthode' sub' ou 'gsub'. Dans le premier exemple, '' foobar ".sub (/ foo (. *) /, '\ 1 \ 1')', ''\'' est dans la portée de la méthode' sub'. Dans le second exemple, '$ 1' est référencé en dehors d'une méthode' sub'/'gsub'. L'exemple montre qu'il est référencé peu après un appel '= ~', mais ce n'est pas pertinent. Apparemment, l'utilisation d'une regex définit '$ 1', qui, en tant que variable globale, peut être référencée n'importe où. – John