2012-06-29 8 views
3

У меня есть текст выглядит следующим образом:Regex заменить текст в Python

Added "a-foo-b" foo. 

Цель состоит в том, чтобы использовать регулярное выражение заменить второй Foo в бар, и оставить первый Foo между двумя двойными кавычками нетронутыми. Таким образом, в приведенном выше тексте, результат я ищу это:

Added "a-foo-b" bar. 

Благодаря

+0

re.sub (r'foo»,„бар“, s) # Это будет заменить все Foo запретить в тексте – xiez

+0

Вы можете рассчитывать на полную стоп терминатора быть там? –

ответ

0

Если текст всегда заканчивается точкой, вы можете попробовать что-то вроде:

echo 'Added "a-foo-b" foo.' | sed s/foo\.$/bar/g 

Added "a-foo-b" bar 
+0

Это не python :-) и пусть OP покажет некоторое усилие перед отправкой ответа ... –

+0

Хорошо, я просто подумал, что увидеть регулярное выражение поможет. :-) –

+0

не беспокойтесь, держите их в покое! Добро пожаловать в SO BTW! –

3
import re 

pat = re.compile(r'("[^"]+".*)foo') 

s = '''Added "a-foo-b" foo.''' 

s_new = re.sub(pat, r'\1bar', s) 
print(s_new) 

Поскольку вы сказали, что цель состоит в том, чтобы оставить один в двойных кавычках в одиночку, я сосредоточился на двойных кавычках в качестве ключа. Круглые скобки образуют «группу соответствия», которая сохраняет совпадающую строку; эта совпадающая группа соответствует двойным кавычкам и тому, что внутри них, а затем шаблон соответствует второму foo. Образец замены заменит все, что мы сопоставим, но это нормально, потому что мы используем \1, чтобы вернуть часть группы матчей, а затем у нас есть bar, чтобы заменить эту секунду foo.

Если вы знаете, что не может быть никаких больше двойные кавычки после foo вы хотите заменить, это может быть лучше картина:

pat = re.compile(r'(".*".*)foo') 

Этот шаблон соответствует двойной кавычки, то ничего, то другой двойные кавычки. Первый шаблон не будет работать, если строка с кавычками содержит скрытую двойную кавычку, но это будет. Но если вы используете этот шаблон на эту строку:

s = '''Added "a-foo-b" foo. "Wow, another foo"''' 

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

EDIT:

Вопрос: Да, что если s = '''Added "a-foo-b" foo.Deleted "a-foo-b".'''

Ответ: Если шаблон всегда имеет место, вы знаете, что не будет беглый двойные кавычки внутри двойных кавычках, и вы можете используйте первый шаблон. Затем вы можете применить несколько шаблонов для обнаружения и/или замены того, что хотите. pat_added ниже решает проблему, которую мы хотели решить ранее; он закрепляет на части строки Added, поэтому он ничего не сделает с частью строки Deleted. Если вы хотите совместить и заменить часть строки внутри котировок, pat_deleted показывает, как это сделать; он имеет три группы соответствия и возвращает первый и последний, чтобы вы могли заменить средний. На самом деле нам не нужна соответствующая группа для средней; мы могли бы оставить часть, которую мы заменяем вне группы соответствия, как это было сделано с первым шаблоном.

import re 
pat_added = re.compile(r'(Added\s+"[^"]+"\s+)\w+') 
pat_deleted = re.compile(r'(Deleted\s+"[a-z]-)([^-]+)(-[a-z]"\.)') 

s = '''Added "a-foo-b" foo.Deleted "a-foo-b".''' 
s = re.sub(pat_added, r'\1bar', s) 
s = re.sub(pat_deleted, r'\1bar\3', s) 
print(s) 
+0

Да, это работает! Большое спасибо! – xiez

+0

Неплохо, но что, если вы хотите пропустить все 'foo'-s в кавычках? –

+0

Да, что, если s = '' 'Добавлено «a-foo-b» foo.Deleted «a-foo-b».' '' – xiez

0

Подход со струнными методами.

>>> s='Added "a-foo-b" foo test' 
>>> needle='foo' 
>>> rind=s.rfind('foo') 
>>> if rind!=-1: 
... s=s[:rind] + needle + s[rind+len(needle):] 
Смежные вопросы