Шаг 30.
Python: сборник рецептов.
Строки и текст. Написание регулярного выражения для многострочных шаблонов

    На этом шаге мы рассмотрим использование флага re.DOTALL при построении регулярных выражений.

Задача

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

Решение

    Эта проблема обычно возникает в шаблонах, которые используют точку (.) для поиска совпадения с любым символом. Многие забывают, что точка не может совпадать с символом новой строки. Например, вы пытаетесь найти совпадения в комментариях в стиле языка С:

>>> comment = re.compile(r'/\*(.*?)\*/')
>>> text1 = '/* this is a comment */'
>>> text2 = '''/* this is a
     multiline comment */
    '''
>>> comment.findall(text1)
[' this is a comment ']
>>> comment.findall(text2)
[]
>>> 

    Чтобы исправить проблему, вам нужно добавить поддержку символов новой строки. Например:

>>> comment = re.compile(r'/\*((?:.|\n)*?)\*/')
>>> comment.findall(text2)
[' this is a\n     multiline comment ']
>>>

    В этом шаблоне (?:.|\n) определяет незахватывающую группу (то есть выражение определяет группу для целей поиска совпадений, но эта группа не захватывается и не подсчитывается).

Обсуждение

    Функция re.compile() принимает полезный в данном случае флаг re.DOTALL. Он заставляет символ "." в регулярном выражении совпадать с любыми символами, включая символ новой строки. Например:

>>> comment = re.compile(r'/\*(.*?)\*/', re.DOTALL)
>>> comment.findall(text2)
[' this is a\n     multiline comment ']
>>> 

    Использование флага re.DOTALL отлично работает в простых случаях, но это может давать сбои при работе с очень сложными шаблонами или сочетанием отдельных регулярных выражений, которые должны объединяться друг с другом для токенизации. Если у вас есть выбор, обычно лучше определить шаблон регулярного выражения, так чтобы он работал правильно без необходимости в дополнительных флагах.

    На следующем шаге мы рассмотрим нормализацию текста в Unicode к стандартному представлению.




Предыдущий шаг Содержание Следующий шаг