Утеча рядок регулярних виразів у Python


229

Я хочу використовувати введення від користувача в якості шаблона регулярного вибору для пошуку по деякому тексту. Це працює, але як я можу впоратися з випадками, коли користувач вводить символи, які мають значення в регулярному вираженні? Наприклад, користувач хоче шукати Word (s): движок regex візьме (s)як групу. Я хочу, щоб це ставилося до нього, як до струни "(s)". Я можу працювати replaceна вході користувача і замінити (з \(і )з , \)але проблема в тому , мені потрібно буде зробити заміну для кожного можливого символу регулярних виразів. Чи знаєте ви якийсь кращий спосіб?

Відповіді:


324

Використовуйте re.escape()для цього функцію:

4.2.3 reЗміст модуля

втеча (рядок)

Зворотний рядок із зворотним прорізом, що не буквено-цифровими; це корисно, якщо ви хочете відповідати довільній рядковій рядку, яка може містити в ній метахарактеристики регулярних виразів.

Спрощений приклад, пошук будь-якого виникнення поданого рядка, необов'язково слідуючи 's', і повернути об'єкт відповідності.

def simplistic_plural(word, text):
    word_or_plural = re.escape(word) + 's?'
    return re.match(word_or_plural, text)

53

Ви можете використовувати re.escape () :

re.escape (рядок) Зворотний рядок із зворотно-косою рисою; це корисно, якщо ви хочете відповідати довільній рядковій рядку, яка може містити в ньому метахарактеристики регулярних виразів.

>>> import re
>>> re.escape('^a.*$')
'\\^a\\.\\*\\$'

3

На жаль, re.escape()не підходить для рядка заміни:

>>> re.sub('a', re.escape('_'), 'aa')
'\\_\\_'

Рішення - поставити заміну в лямбда:

>>> re.sub('a', lambda _: '_', 'aa')
'__'

тому що повернене значення лямбда трактується re.sub()як буквальний рядок.


3
replАргумент re.subє рядком, а не регулярною вираз; звертатися re.escapeдо нього не має сенсу в першу чергу.
трійка

5
@tripleee Це неправильно, replаргумент не є простим рядком, він розбирається. Наприклад, re.sub(r'(.)', r'\1', 'X')повернеться X, ні \1.
Flimm

4
Ось важливе питання для втечі replаргументу: stackoverflow.com/q/49943270/247696
Флімм

3
Змінено у версії 3.3: Символ "_" більше не можна уникнути. Змінено у версії 3.7: Уникають лише символи, які можуть мати особливе значення у звичайному виразі. (Чому це зайняло так багато часу?)
Cees Timmerman

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.