Регулярное выражение Python соответствует только в автономном режиме

Используя re в python3, я хочу сопоставить появление процентов в тексте и заменить их специальным токеном (например, заменить «30% -ное увеличение» на «A @ процент @ увеличение»).

Я хочу найти совпадение только в том случае, если процентное выражение является отдельным элементом. Например, он не должен соответствовать «Код продукта A322% n43%». Однако он должен совпадать, если строка содержит только одно процентное выражение, например «89%».

Я пробовал использовать разделители в своем регулярном выражении, например \ b, но поскольку% сам по себе не является буквенно-цифровым символом, он не улавливает конец выражения. Использование \ s делает невозможным уловить выражение, стоящее отдельно в строке.

На данный момент у меня есть код:

>>> re.sub(r"[+-]?[.,;]?(\d+[.,;']?)+%", ' @percent@ ', "1,211.21%")
' @percent '

который по-прежнему соответствует, если за выражением следуют буквы или другой текст (например, в примере кода продукта выше).

>>> re.sub(r"[+-]?[.,;]?(\d+[.,;']?)+%", ' @percent@ ', "EEE1,211.21%asd")
'EEE @percent@ asd'

Что ты посоветуешь?

Попробуйте re.sub(r'(?<!\w)-?\d[\d.,]*\b%\B', '@percent@', s).

Wiktor Stribiżew 02.06.2018 12:39
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
1
158
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Попробуйте поставить «первую» группу захвата на «вторую».

original: r"[+-]?[.,;]?(\d+[.,;']?)+%"
suggestd: r"[+-]?[.,;]?((\d+[.,;']?)+%)\b"

это не сработало, он все еще не определяет границу слова. Не работает, с "3%" в строке, само по себе, например

glicerico 03.06.2018 06:30
Ответ принят как подходящий

Похоже, идеальная работа для отрицательного просмотра назад и отрицательного просмотра вперед:

re.sub(r'''(?<![^\s]) [+-]?[.,;]? (\d+[.,;']?)+% (?![^\s.,;!?'"])''', 
       '@percent@', string, flags=re.VERBOSE)

(?<![^\s]) означает «отсутствие пробелов непосредственно перед текущей позицией разрешено» (при необходимости добавьте запрещенные символы).

(?![^\s.,;!?'"]) означает «запрещены пробелы, точки и т. д. Сразу после текущей позиции».

Демо: https://regex101.com/r/khV7MZ/1.

Отличный ответ. Предложение работает идеально, включает больше случаев, чем я считал (например, он отлично определяет 5% в «Вы сказали 5%?»), А инструмент, на который вы ссылаетесь, очень полезен! Спасибо.

glicerico 03.06.2018 06:33

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

glicerico 03.06.2018 07:18

@AndresSuarez Пробелы игнорируются из-за flags=re.VERBOSE (но в [ ] пробелы не игнорируются). Тройные кавычки используются, чтобы избежать экранирования ' и ".

Kirill Bulygin 03.06.2018 18:13

Примечание принято! Спасибо @Kirill

glicerico 04.06.2018 13:58

Другие вопросы по теме