2009-09-08 3 views
2

Есть ли аналогичная функция в python, которая выполняет поиск (array) и replace (array) в качестве параметра? Затем берет значение из каждого массива и использует их для поиска и замены объекта (строки).аналогичная функция для str_replace php в python?

Я знаю, что могу добиться этого, используя петли, но просто выглядя более элегантным способом.

+0

Смотреть предыдущей: http://stackoverflow.com/questions/1175540/iterative-find-replace-from-a-list -of-tuples-in-python/1175554 # 1175554 – 2009-09-08 01:05:50

ответ

11

Я считаю, что ответ отрицательный.

Я хотел бы указать, поиска/замены строк в списке, и итерация над ним:

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

Даже если питон имел str_replace -style функцию, я думаю, что я бы еще отделить свой поиск/замените строки как список, так что на самом деле это только одна дополнительная строка кода.

Наконец, это язык программирования в конце концов. Если он не предоставляет нужную вам функцию, вы всегда можете определить ее самостоятельно.

+1

Да, вы совершенно. но встроенные функции, как правило, более эффективны. – Mohamed

+0

Проблема с этим решением заключается в том, что редактирование # 2 может заменить что-то, вставленное редактированием перед ним, чего я ожидаю, что его абсолютно избежать. – u0b34a0f6ae

+0

@ kaizer.se: Да, это правда. Я не знаю PHP, но http://nz.php.net/str_replace говорит: «Если поиск или замена являются массивами, их элементы обрабатываются в первую очередь». Думаю, только замена неперекрывающихся строк поиска была бы трудной проблемой. –

1

Делайте это с регулярными выражениями:

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" 

Использование регулярных выражений для этого делает поиск быстро. Это не будет итеративно заменять замену на дополнительные замены, то есть обычно что нужно.

2

Хех - вы можете использовать один вкладыш ниже которого элегантность уступает только удобству :-P

(действует как PHP при поиске больше, чем заменить, тоже, если я правильно прочитал, что в PHP docs.):

**** Редактировать: Эта новая версия предназначена для замены всех подстрок всех размеров. ****

>>> 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

Уход. Itertools могут продолжать последовательности лучше: 'def cont (seq, elem = None): return itertools.chain (seq, itertools.repeat (elem))'; теперь используйте 'cont (replace, '')' – u0b34a0f6ae

0

Сделан крошечная рекурсивная функция для этого

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);