2009-09-08 4 views
2

Y at-il une fonction similaire dans python qui prend la recherche (tableau) et remplace (tableau) en tant que paramètre? Puis prend une valeur de chaque tableau et les utilise pour faire une recherche et remplacer sur le sujet (chaîne).fonction similaire à str_replace de php en python?

Je sais que je peux réaliser ceci en utilisant des boucles, mais en regardant simplement de manière plus élégante.

+0

Voir précédente: http://stackoverflow.com/questions/1175540/iterative-find-replace-from-a-list -of-tuples-in-python/1175554 # 1175554 –

Répondre

11

Je crois que la réponse est non.

Je préciserais votre recherche/remplacer des chaînes dans une liste, et itérer dessus:

edits = [(search0, replace0), (search1, replace1), (search2, replace2)] # etc. 
for search, replace in edits: 
    s = s.replace(search, replace) 

Même si python avait une str_replace fonction de style, je pense que je serais toujours séparer ma recherche/remplacez les chaînes par une liste, donc cela ne prend qu'une ligne de code supplémentaire.

Enfin, il s'agit d'un langage de programmation après tout. Si elle ne fournit pas la fonction que vous voulez, vous pouvez toujours la définir vous-même.

+1

oui, vous êtes rigth. mais les fonctions intégrées ont tendance à être plus efficaces. – Mohamed

+0

Le problème avec cette solution est que l'édition n ° 2 pourrait remplacer quelque chose inséré par les modifications précédentes, que je m'attendrais absolument à éviter. – u0b34a0f6ae

+0

@ kaizer.se: Oui, c'est vrai. Je ne connais pas PHP mais http://nz.php.net/str_replace dit: "Si search ou replace sont des tableaux, leurs éléments sont traités en premier pour durer." Le seul remplacement des chaînes de recherche qui ne se chevauchent pas serait un problème difficile, je pense. –

1

le faire avec regexps:

import re 

def replace_from_list(replacements, str): 
    def escape_string_to_regex(str): 
     return re.sub(r"([\\.^$*+?{}[\]|\(\)])", r"\\\1", str) 

    def get_replacement(match): 
     return replacements[match.group(0)] 

    replacements = dict(replacements) 
    replace_from = [escape_string_to_regex(r) for r in replacements.keys()] 
    regex = "|".join(["(%s)" % r for r in replace_from]) 
    repl = re.compile(regex) 

    return repl.sub(get_replacement, str) 

# Simple replacement: 
assert replace_from_list([("in1", "out1")], "in1") == "out1" 

# Replacements are never themselves replaced, even if later search strings match 
# earlier destination strings: 
assert replace_from_list([("1", "2"), ("2", "3")], "123") == "233" 

# These are plain strings, not regexps: 
assert replace_from_list([("...", "out")], "abc ...") == "abc out" 

L'utilisation des expressions rationnelles pour ce qui rend la recherche rapide. Cela ne remplacera pas itérativement les remplacements par d'autres remplacements, ce qui est habituellement ce qui est recherché.

2

Heh - vous pouvez utiliser celui-liner ci-dessous dont l'élégance est la deuxième à sa convenance :-P

(Actes comme PHP lorsque la recherche est plus longue que remplacer, aussi, si je lis que correctement dans le PHP docs.):

**** Edit: Cette nouvelle version fonctionne pour toutes les sous-chaînes de taille à remplacer. ****

>>> subject = "Coming up with these convoluted things can be very addictive." 
>>> search = ['Coming', 'with', 'things', 'addictive.', ' up', ' these', 'convoluted ', ' very'] 
>>> replace = ['Making', 'Python', 'one-liners', 'fun!'] 
>>> reduce(lambda s, p: s.replace(p[0],p[1]),[subject]+zip(search, replace+['']*(len(search)-len(replace)))) 
'Making Python one-liners can be fun!' 
+0

Neat. Itertools peut mieux continuer les séquences: 'def cont (seq, elem = None): retourne itertools.chain (seq, itertools.repeat (elem))'; utilisez maintenant 'cont (replace, '')' – u0b34a0f6ae

0

Fait une fonction récursive minuscule pour cette

def str_replace(sbjct, srch, rplc): 
    if len(sbjct) == 0: 
     return '' 

    if len(srch) == 1: 
     return sbjct.replace(srch[0], rplc[0]) 

    lst = sbjct.split(srch[0]) 
    reslst = [] 
    for s in lst: 
     reslst.append(str_replace(s, srch[1:], rplc[1:])) 
    return rplc[0].join(reslst); 
Questions connexes