неожиданный результат для python re.sub () с не захватывающим символом

1

Я не могу понять следующий результат:

import re 

re.sub(r'(?:\s)ff','fast-forward',' ff')
'fast-forward'

Согласно документации:

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

Итак, почему пробелы включены в захваченное событие, а затем заменены, так как я добавил к нему не захватывающий тег?

Я хотел бы получить следующий результат:

' fast-forward'
Теги:

2 ответа

2
Лучший ответ

Группа, не связанная с захватом, по- прежнему соответствует и потребляет согласованный текст. Обратите внимание, что потребление означает добавление согласованного текста в значение соответствия (буфер памяти, выделенный для всей согласованной подстроки) и соответствующее продвижение индекса регулярного выражения. Итак, (?:\s) помещает пробел в значение соответствия и заменяется на ff.

Вы хотите использовать внешний вид, чтобы проверить шаблон без его использования:

re.sub(r'(?<=\s)ff','fast-forward',' ff')

См. Демо-версию regex.

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

re.sub(r'(\s)ff',r'\1fast-forward',' ff')
         ^  ^      ^^ 

Здесь (\s) сохраняет пробелы в буфере памяти Group 1, а \1 в замене, извлекает его и добавляет к результату замены строки.

См. Демонстрацию Python:

import re 
print('"{}"'.format(re.sub(r'(?<=\s)ff','fast-forward',' ff')))
# => " fast-forward"
0

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

Хотя, если вы хотите использовать просмотровую позади для пробельного, вы можете рассмотреть вопрос об использовании граничного слова метасимвола \b вместо этого. Он соответствует пустой строке между символами \w и \W, утверждая, что ваш шаблон находится в начале слова.

import re

re.sub(r'\bff\b', 'fast-forward', ' ff') # ' fast-forward'

Добавление trailing \b также гарантирует, что вы будете только соответствовать 'ff' если он окружен пробелами, а не в начале слова, например, в 'ffoo'.

См. Демонстрацию.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню