Comment remplacer plusieurs sous-chaînes d'une chaîne de caractères?
Je voudrais utiliser l' .fonction remplacer de remplacer les multiples chaînes.
J'ai actuellement
string.replace("condition1", "")
mais aimerait avoir quelque chose comme
string.replace("condition1", "").replace("condition2", "text")
bien que cela ne se sent pas la bonne syntaxe
quelle est la bonne façon de le faire? un peu comme la façon de grep/regex que vous pouvez faire \1
et \2
pour remplacer les champs de certaines chaînes de recherche
- Avez-vous essayé toutes les solutions proposées? Lequel est le plus rapide?
Vous devez vous connecter pour publier un commentaire.
Voici un court exemple qui devrait faire l'affaire avec des expressions régulières:
Par exemple:
sub()
appelée une fois par dictionnaire de paires clé-valeur?"spamham sha".replace("spam", "eggs").replace("sha","md5")
être"eggmd5m md5"
au lieu de"eggsham md5"
m.group(0)
comme ceci:lambda m: rep[re.escape(m.group(0))]
. En outre, votre code ne fonctionnera pas sur les chaînes contenant plusieurs lignes: vous devez ajouterre.M
dansre.compile
.re.M
option (qui ne fera que changer le sens de^
et$
).pattern = ...
. Voir ma réponse ci-dessous.pattern = re.compile("|".join(re.escape(k) for k in rep))
et puistext = pattern.sub(lambda m: rep[m.group(0)], text)
m
) et retourne le résultat de l'expression suivante. Alternativement, vous pourriez faire une fonction nomméedef replace_conditions(text, rep): return rep[re.escape(text.group(0))]
, affecter une variable à votre textetext = "(condition1) and --condition2--"
et appel ?sub
avec le modèle résultant de cette fonction et le texte original:pattern.sub(replace_conditions(text, rep), text)
.mystring.replace({'condition1': '', 'condition2': 'text'})
Vous pourriez juste faire une belle petite boucle de la fonction.
où
text
est l'intégralité de la chaîne etdic
est un dictionnaire chaque définition est une chaîne de caractères à remplacer un match pour le terme.Note: en Python 3,
iteritems()
a été remplacé paritems()
Attention: Python dictionnaires ne pas avoir un bon de commande pour l'itération. Cette solution ne résout votre problème si:
Par exemple:
Possible sortie n ° 1:
Possible sortie n ° 2
Une solution possible est d'utiliser un OrderedDict.
De sortie:
Attention n ° 2: Inefficace si votre
text
chaîne est trop grand ou il y a beaucoup de paires dans le dictionnaire.dic
définitionOrderedDict
- ou une liste de 2-tuples.Ici est une variante de la première solution à l'aide de réduire, dans le cas où vous aimez être fonctionnelle. 🙂
martineau est encore mieux version:
repls
une séquence de n-uplets et de faire disparaître laiteritems()
appel. c'est à direrepls = ('hello', 'goodbye'), ('world', 'earth')
etreduce(lambda a, kv: a.replace(*kv), repls, s)
. Fonctionne également inchangé en Python 3.reduce
a été supprimé.functools
module (voir le docs) en Python 3, donc quand j'ai dit inchangé, je voulais le même code peut être exécuté,—bien que, certes, il faudrait quereduce
a étéimport
ed si nécessaire, puisqu'il n'est plus construit.Pourquoi pas une solution de ce genre?
C'est juste un plus concis récapitulatif de F. J et MiniQuark de grandes réponses. Tous vous avez besoin pour réaliser multiples et simultanées de la chaîne de remplacement est la fonction suivante:
Utilisation:
Si vous le souhaitez, vous pouvez faire votre propre dédié fonctions de remplacement à partir de ce plus simple.
rep_dict = {"but": "mut", "mutton": "lamb"}
la chaîne"button"
résultats dans"mutton"
avec votre code, mais donnerait"lamb"
si les remplacements étaient enchaînés les uns après les autres.Do you prefer cafe? No, I prefer cafe.
, ce qui n'est pas desiderable à tous.J'ai construit ce moment de F. J. s excellente réponse:
One shot utilisation:
Noter que depuis le remplacement est effectué en une seule passe, "café" modifications "thé", mais il n'est pas à nouveau "café".
Si vous avez besoin de faire le remplacement de nombreuses fois, vous pouvez créer une fonction de remplacement facilement:
Améliorations:
Profitez-en! 🙂
pattern.sub
s'attend à une fonction avec un seul paramètre (le texte à remplacer), de sorte que la fonction doit avoir accès àreplace_dict
.re.M
permet Multiligne remplacements (c'est bien expliqué dans la doc: docs.python.org/2/library/re.html#re.M).Je voudrais proposer l'utilisation de la chaîne de modèles. Il suffit de placer la chaîne à être remplacé dans un dictionnaire et tout est réglé! Exemple de docs.python.org
substitute
soulève une exception, donc soyez prudent lors de l'obtention de modèles auprès des utilisateurs.Dans mon cas, j'avais besoin d'un simple remplacement de clés uniques avec des noms, alors j'ai pensé à ceci:
i
avecs
vous désirez obtenir un comportement bizarre.b = [ ['i', 'Z'], ['s', 'Y'] ]; for x,y in (b): a = a.replace(x, y)
Alors si vous faites attention à l'ordre de votre tableau de paires que vous pouvez vous assurer de ne pas remplacer les() de manière récursive.Ici mon de 0,02$. Il est basé sur Andrew Clark réponse, juste un peu plus clair, et il couvre également le cas lorsqu'une chaîne de caractères à remplacer une sous-chaîne d'une autre chaîne de caractères à remplacer (à longue chaîne victoires)
C'est dans ce ce gist, n'hésitez pas à modifier si vous avez la moindre proposition.
De départ
Python 3.8
, et l'introduction de affectation des expressions (PEP 572) (:=
opérateur), nous pouvons appliquer les remplacements au sein d'une compréhension de liste:J'ai besoin d'une solution où les chaînes de caractères à remplacer peut être une des expressions régulières,
par exemple, pour aider à normaliser un long texte, en remplaçant plusieurs caractères espace avec un seul. Bâtiment sur une chaîne de réponses des autres, y compris MiniQuark et mmj, c'est ce que je suis venu avec:
Il travaille pour les exemples donnés dans d'autres réponses, par exemple:
La chose principale pour moi est que vous pouvez utiliser des expressions régulières ainsi, par exemple, de remplacer les mots entiers uniquement, ou à normaliser l'espace blanc:
Si vous souhaitez utiliser le dictionnaire clés comme normal chaînes,
vous pouvez échapper à ceux d'avant l'appel de multiple_replace par exemple à l'aide de cette fonction:
La fonction suivante peut vous aider à trouver erronée des expressions régulières entre vos clés de dictionnaire (depuis le message d'erreur de multiple_replace n'est pas très parlant):
Noter qu'il n'enchaîne pas les remplacements, plutôt effectue simultanément. Cela le rend plus efficace sans pour autant nuire à ce qu'il peut faire. Pour imiter l'effet de chaînage, vous aurez juste besoin d'ajouter plus de chaîne de remplacement des paires et de garantir les attendus de la commande de l'paires:
Je suggère que le code devrait être, par exemple:
Il aura l'impression de tous les changements demandés.
Vous devriez vraiment pas faire de cette façon, mais je trouve ça juste trop cool:
Maintenant,
answer
est le résultat de tous les remplacements à son tourencore une fois, c'est très hacky et n'est pas quelque chose que vous devriez être en utilisant régulièrement. Mais c'est juste agréable de savoir que vous pouvez faire quelque chose comme cela, si jamais vous avez besoin de.
exec
, même si c'est juste un hacky solution.Voici un exemple de ce qui est plus efficace sur les longues chaînes de caractères avec beaucoup de petits remplacements.
Le point est en évitant un grand nombre de concaténations de chaînes longues. Nous coupons la chaîne source à des fragments, en remplaçant certains des fragments, comme nous le formulaire de la liste, puis joignez le tout à revenir dans une chaîne de caractères.
Je ne sais pas à propos de la vitesse, mais c'est mon quotidien quick fix:
... mais j'aime bien le n ° 1 de la regex de la réponse ci-dessus. Remarque - si une nouvelle valeur est une sous-chaîne d'une autre puis l'opération n'est pas commutative.
Ou juste pour un rapide hack:
Voici un autre moyen de le faire avec un dictionnaire:
À 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 sur le dossier ouvert pour effectuer les remplacements. Le script charge le mappage à partir d'un fichier externe dans laquelle vous pouvez définir le séparateur. Je suis un débutant mais j'ai trouvé ce script très utile lors de la réalisation de plusieurs substitutions dans plusieurs fichiers. Il a chargé un dictionnaire avec plus de 1 000 entrées en quelques secondes. Il n'est pas très élégant, mais il a travaillé pour moi
c'est ma solution pour le problème. Je l'ai utilisé dans un chatbot, de remplacer les différents mots à la fois.
cela va devenir
The cat hunts the dog
Un autre exemple :
Liste d'entrée
La sortie désirée serait
Code :