Je voudrais utiliser la fonction .replace pour remplacer plusieurs chaînes.
J'ai actuellement
string.replace("condition1", "")
mais aimerait avoir quelque chose comme
string.replace("condition1", "").replace("condition2", "text")
bien que cela ne ressemble pas à une bonne syntaxe
quelle est la bonne façon de procéder? un peu comme comment dans grep / regex vous pouvez faire \1
et \2
remplacer les champs de certaines chaînes de recherche
Réponses:
Voici un court exemple qui devrait faire l'affaire avec des expressions régulières:
Par exemple:
la source
"spamham sha".replace("spam", "eggs").replace("sha","md5")
étant au"eggmd5m md5"
lieu de"eggsham md5"
Vous pourriez juste faire une jolie petite fonction de bouclage.
où
text
est la chaîne complète etdic
est un dictionnaire - chaque définition est une chaîne qui remplacera une correspondance avec le terme.Remarque : en Python 3,
iteritems()
a été remplacé paritems()
Attention: les dictionnaires Python n'ont pas d'ordre d'itération fiable. Cette solution ne résout votre problème que si:
Par exemple:
Sortie possible n ° 1:
Sortie possible # 2
Une solution possible consiste à utiliser un OrderedDict.
Production:
Attention # 2: inefficace si votre
text
chaîne est trop grande ou s'il y a beaucoup de paires dans le dictionnaire.la source
OrderedDict
- ou une liste de 2 tuples.Pourquoi pas une solution comme celle-ci?
la source
Voici une variante de la première solution utilisant réduire, au cas où vous aimeriez être fonctionnel. :)
la version encore meilleure de martineau:
la source
repls
une séquence de tuples et de supprimer l'iteritems()
appel. c'est à direrepls = ('hello', 'goodbye'), ('world', 'earth')
etreduce(lambda a, kv: a.replace(*kv), repls, s)
. Fonctionnerait également inchangé en Python 3.reduce
a été supprimé .reduce
existe toujours, mais il a été intégré aufunctools
module (voir les docs ) en Python 3, donc quand j'ai dit inchangé, je voulais dire que le même code pouvait être exécuté - bien qu'il soit vrai qu'il faudrait qu'ilreduce
ait étéimport
édité si nécessaire car ce n'est plus un intégré.Ceci est juste un récapitulatif plus concis des bonnes réponses FJ et MiniQuark. Tout ce dont vous avez besoin pour réaliser plusieurs remplacements de chaînes simultanés est la fonction suivante:
Usage:
Si vous le souhaitez, vous pouvez créer vos propres fonctions de remplacement dédiées à partir de celle-ci plus simple.
la source
rep_dict = {"but": "mut", "mutton": "lamb"}
la chaîne"button"
résulte"mutton"
avec votre code, mais donnerait"lamb"
si les remplacements étaient enchaînés, l'un après l'autre.Do you prefer cafe? No, I prefer cafe.
, ce qui n'est pas du tout souhaitable .J'ai construit cela sur l'excellente réponse des FJ:
Utilisation unique:
Notez que le remplacement étant effectué en un seul passage, "café" devient "thé", mais ne revient pas à "café".
Si vous devez effectuer le même remplacement plusieurs fois, vous pouvez facilement créer une fonction de remplacement:
Améliorations:
Prendre plaisir! :-)
la source
pattern.sub
la fonction attend un seul paramètre (le texte à remplacer), la fonction doit donc y avoir accèsreplace_dict
.re.M
permet les remplacements multilignes (il est bien expliqué dans le doc: docs.python.org/2/library/re.html#re.M ).Je voudrais proposer l'utilisation de modèles de chaînes. Placez simplement la chaîne à remplacer dans un dictionnaire et tout est réglé! Exemple tiré de docs.python.org
la source
substitute
déclenche une exception, soyez donc prudent lorsque vous obtenez des modèles des utilisateurs.Dans mon cas, j'avais besoin d'un simple remplacement de clés uniques par des noms, alors j'ai pensé à ça:
la source
i
pars
vous obtiendriez un comportement étrange.b = [ ['i', 'Z'], ['s', 'Y'] ]; for x,y in (b): a = a.replace(x, y)
Alors si vous faites attention à ordonner vos paires de tableaux, vous pouvez vous assurer de ne pas remplacer () récursivement.A partir du lancement
Python 3.8
et de l'introduction des expressions d'affectation (PEP 572) (:=
opérateur), nous pouvons appliquer les remplacements dans une liste de compréhension:la source
['The quick red fox jumps over the lazy dog', 'The quick red fox jumps over the quick dog']
. Mais l'expression d'affectation (text := text.replace
) crée également de manière itérative de nouvelles versions detext
en la mutant. Après la compréhension de la liste, vous pouvez utiliser latext
variable qui contient le texte modifié.text
en une ligne, vous pouvez également utiliser[text := text.replace(a, b) for a, b in replacements][-1]
(notez le[-1]
), qui extrait le dernier élément de la liste de compréhension; c'est-à-dire la dernière version detext
.Voici mon 0,02 $. Il est basé sur la réponse d'Andrew Clark, juste un peu plus clair, et il couvre également le cas où une chaîne à remplacer est une sous-chaîne d'une autre chaîne à remplacer (une chaîne plus longue gagne)
C'est dans ce sens , n'hésitez pas à le modifier si vous avez une proposition.
la source
J'avais besoin d'une solution où les chaînes à remplacer peuvent être des expressions régulières, par exemple pour aider à normaliser un long texte en remplaçant plusieurs espaces blancs par un seul. S'appuyant sur une chaîne de réponses provenant d'autres personnes, notamment MiniQuark et mmj, voici ce que j'ai trouvé:
Cela fonctionne pour les exemples donnés dans d'autres réponses, par exemple:
L'essentiel pour moi est que vous pouvez également utiliser des expressions régulières, par exemple pour remplacer uniquement des mots entiers, ou pour normaliser un espace blanc:
Si vous souhaitez utiliser les clés du dictionnaire comme des chaînes normales, vous pouvez les échapper avant d'appeler multiple_replace en utilisant par exemple cette fonction:
La fonction suivante peut aider à trouver des expressions régulières erronées parmi vos clés de dictionnaire (car le message d'erreur de multiple_replace n'est pas très révélateur):
Notez qu'il ne chaîne pas les remplacements, mais les effectue simultanément. Cela le rend plus efficace sans contraindre ce qu'il peut faire. Pour imiter l'effet du chaînage, vous devrez peut-être simplement ajouter plus de paires de remplacement de chaîne et garantir l'ordre attendu des paires:
la source
Voici un exemple plus efficace sur les longues chaînes avec de nombreux petits remplacements.
Le but est d'éviter de nombreuses enchaînements de longues chaînes. Nous découpons la chaîne source en fragments, en remplaçant certains des fragments au fur et à mesure que nous formons la liste, puis joignons le tout en une chaîne.
la source
Vous ne devriez vraiment pas le faire de cette façon, mais je trouve ça trop cool:
Maintenant,
answer
est le résultat de tous les remplacements à son tourencore une fois, c'est très hacky et ce n'est pas quelque chose que vous devriez utiliser régulièrement. Mais c'est juste agréable de savoir que vous pouvez faire quelque chose comme ça si jamais vous en avez besoin.
la source
Je me débattais aussi avec ce problème. Avec de nombreuses substitutions, les expressions régulières ont du mal et sont environ quatre fois plus lentes que le bouclage
string.replace
(dans mes conditions d'expérience).Vous devez absolument essayer d'utiliser la bibliothèque Flashtext ( article de blog ici , Github ici ). Dans mon cas, c'était un peu plus de deux ordres de grandeur plus rapide, de 1,8 s à 0,015 s (les expressions régulières ont pris 7,7 s) pour chaque document.
Il est facile de trouver des exemples d'utilisation dans les liens ci-dessus, mais c'est un exemple de travail:
Notez que Flashtext effectue des substitutions en une seule passe (pour éviter que a -> b et b -> c ne traduisent «a» en «c»). Flashtext recherche également des mots entiers (donc «est» ne correspondra pas à «th is »). Cela fonctionne très bien si votre cible est de plusieurs mots (en remplaçant «C'est» par «Bonjour»).
la source
<p>
par/n
. J'ai essayé votre approche mais avec des balises flashtext ne semble pas l'analyser?<
et>
marquer la fin d'un mot (mais être inclus dans le remplacement)?Je pense que cette question a besoin d'une réponse de fonction lambda récursive sur une seule ligne pour être complète, juste parce que. Donc là:
Usage:
Remarques:
Remarque: Comme pour toutes les fonctions récursives en python, une profondeur de récursivité trop grande (c'est-à-dire des dictionnaires de remplacement trop grands) entraînera une erreur. Voir par exemple ici .
la source
sys.getrecursionlimit()
c'est un couple de 1000, max. utilisez une boucle ou quelque chose comme ça, ou essayez de simplifier les substitutions.Je ne connais pas la vitesse mais c'est ma solution rapide de travail:
... mais j'aime la réponse regex n ° 1 ci-dessus. Remarque - si une nouvelle valeur est une sous-chaîne d'une autre, l'opération n'est pas commutative.
la source
Vous pouvez utiliser la
pandas
bibliothèque et lareplace
fonction qui prend en charge les correspondances exactes ainsi que les remplacements d'expressions régulières. Par exemple:Et le texte modifié est:
Vous pouvez trouver un exemple ici . Notez que les remplacements sur le texte se font dans l'ordre où ils apparaissent dans les listes
la source
Pour remplacer un seul caractère, utilisez les touches
translate
etstr.maketrans
est ma méthode préférée.tl; dr>
result_string = your_string.translate(str.maketrans(dict_mapping))
démo
la source
À partir de la précieuse réponse d'Andrew, j'ai développé un script qui charge le dictionnaire à partir d'un fichier et élabore tous les fichiers du dossier ouvert pour effectuer les remplacements. Le script charge les mappages à partir d'un fichier externe dans lequel vous pouvez définir le séparateur. Je suis débutant mais j'ai trouvé ce script très utile lors de plusieurs substitutions dans plusieurs fichiers. Il a chargé un dictionnaire avec plus de 1000 entrées en quelques secondes. Ce n'est pas élégant mais ça a fonctionné pour moi
la source
c'est ma solution au problème. Je l'ai utilisé dans un chatbot pour remplacer les différents mots à la fois.
cela deviendra
The cat hunts the dog
la source
Un autre exemple: liste d'entrée
La sortie souhaitée serait
Code:
la source
Ou tout simplement pour un hack rapide:
la source
Voici une autre façon de le faire avec un dictionnaire:
la source