Remplacer les mots d'une chaîne - Ruby

282

J'ai une chaîne en Ruby:

sentence = "My name is Robert"

Comment puis-je remplacer n'importe quel mot dans cette phrase facilement sans utiliser de code complexe ou une boucle?

Mithun Sasidharan
la source
Remplacer de quelle manière? Remplacer un mot arbitraire (mot # 2) ou un mot spécifique ( my)?
Blender
Merci pour votre question courte, simple et utile. cela m'a aidé à trouver une solution pour styliser les hashtags à mon avis
Stef Hej

Réponses:

496
sentence.sub! 'Robert', 'Joe'

Ne provoquera pas d'exception si le mot remplacé n'est pas dans la phrase (la []=variante le fera).

Comment remplacer toutes les instances?

Ce qui précède ne remplace que la première instance de "Robert".

Pour remplacer toutes les instances, utilisez gsub/ gsub!(c'est-à-dire "substitution globale"):

sentence.gsub! 'Robert', 'Joe'

Ce qui précède remplacera toutes les instances de Robert par Joe.

srcspider
la source
Cela semble remplacer uniquement la première instance, ce qui est bien sûr parfois bien et parfois non.
Jason Swett
1
@JasonSwett a mis à jour la réponse pour savoir comment remplacer toutes les instances.
srcspider
128

Si vous avez affaire à du texte en langage naturel et que vous devez remplacer un mot, pas seulement une partie d'une chaîne, vous devez ajouter une pincée d'expressions régulières à votre sous-section car une substitution de texte brut peut entraîner des résultats désastreux:

'mislocated cat, vindicating'.gsub('cat', 'dog')
=> "mislodoged dog, vindidoging"

Les expressions régulières ont des limites de mots, telles que celles \bqui correspondent au début ou à la fin d'un mot. Donc,

'mislocated cat, vindicating'.gsub(/\bcat\b/, 'dog')
=> "mislocated dog, vindicating"

Dans Ruby, contrairement à d'autres langues comme Javascript, les limites de mots sont compatibles UTF-8, vous pouvez donc les utiliser pour les langues avec des alphabets latins non latins ou étendus:

'сіль у кисіль, для весіль'.gsub(/\bсіль\b/, 'цукор')
=> "цукор у кисіль, для весіль"
Hnatt
la source
6
Notez que certaines langues n'utilisent même pas d'espaces, donc \bne fonctionnent pas dedans, vous auriez besoin d'utiliser des analyseurs morphologiques ou des trucs comme ça dans ces cas. Aussi, +1 pour un exemple hilarant.
NiñoScript
57

Vous pouvez essayer d'utiliser de cette façon:

sentence ["Robert"] = "Roger"

La phrase deviendra alors:

sentence = "My name is Roger" # Robert is replaced with Roger
Mithun Sasidharan
la source
4
C'est assez intéressant. Je n'ai jamais vu cette méthode de remplacement auparavant.
Sean Hill
6
N'obtiendrez-vous pas une erreur avec cette méthode si la chaîne d'origine ne contient pas le mot que vous essayez de remplacer?
srcspider
2
Assurez-vous simplement de reprendre IndexError. Sinon, pour un mot ne faisant pas partie de la phrase, il en résultera:string not matched (IndexError)
Konrad Reiche
9
Un autre problème avec cette méthode est qu'elle ne remplace que la première instance de la chaîne.
Martin Konecny
14
Ceci est intéressant, mais ne devrait certainement pas être marqué comme la bonne réponse.
Niels Abildgaard
46

Tout d'abord, vous ne déclarez pas le type dans Ruby, vous n'avez donc pas besoin du premier string.

Pour remplacer un mot dans la chaîne, vous faites: sentence.gsub(/match/, "replacement").

Sean Hill
la source