Замена только определенной группы внутри согласованного выражения

58
10

Я разбираю текст, в котором я хотел бы внести изменения, но только в конкретные строки.

У меня есть шаблон регулярного выражения, который ловит всю строку, если она представляет интерес, и в выражении у меня есть запоминающаяся группа вещей, которую я бы действительно хотел изменить.

Я хотел бы иметь возможность изменять только определенную группу внутри согласованного выражения, а не заменять все выражение (которое заменило бы всю строку).

Например:

У меня есть текстовый файл с:

This is a completely silly example.
something something "this should be replaced" bla.
more uninteresting stuff

И у меня есть регулярное выражение: pattern = '.*("[^"]*").*'

Затем я поймаю вторую строку, но я бы заменил только "this should be replaced" согласованную группу внутри строки, а не всю строку. (так что использование re.sub(pattern, replacement, string) не будет выполнять эту работу.

Заранее спасибо!

спросил(а) 2012-02-20T14:19:00+04:00 8 лет, 7 месяцев назад
1
Решение
70

Ответ на eumiro лучше всего в этом случае, но для полноты, если вам действительно нужно выполнить более сложную обработку текста pre, inside и post, вы можете просто использовать несколько групп, например:

'(.*)("[^"]*")(.*)'

(первая группа предоставляет текст до, третий текст после, делает то, что вам нравится с ними)

Кроме того, вы можете предпочесть запретить "в предварительной части:

'([^"]*)("[^"]*")(.*)'

ответил(а) 2012-02-20T14:33:00+04:00 8 лет, 7 месяцев назад
70

Что не так с

r'"[^"]+"'

Ваш .* До и после согласованного выражения совпадает с нулевой длиной строки, так что вам это совсем не нужно.

re.sub(r'"[^"]+"', 'DEF', 'abc"def"ghi')
# returns 'abcDEFghi'

и ваш текст примера приведет к:

'This is a completely silly example.\nsomething something DEF bla.\nmore uninteresting stuff

ответил(а) 2012-02-20T14:22:00+04:00 8 лет, 7 месяцев назад
58

re.match и re.search возвращают "объект соответствия". (См. Документацию на python). Предположим, что вы хотите заменить группу 3 в своем RE, вытащите ее начальные/конечные индексы и сразу замените подстроку:

mobj = re.match(pattern, line)
start = mobj.start(3)
end = mobj.end(3)
line = line[:start] + replacement + line[end:]

ответил(а) 2012-02-20T18:59:00+04:00 8 лет, 7 месяцев назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема