Существует ли Python, эквивалентный модификатору Perl «/ x» для регулярных выражений?

#python #regex #pandas

#python #регулярное выражение #perl

Вопрос:

Perl упрощает создание удобочитаемых регулярных выражений с использованием /x модификатора. Этот модификатор позволяет записывать строки регулярных выражений и игнорировать все пробелы в этих строках. Другими словами, логические части регулярного выражения могут быть разделены пробелами или даже возвратами каретки, что обеспечивает отличную читаемость. В Python единственный способ, который я вижу для этого, — создать такую строку регулярного выражения, удалить из нее пробелы на промежуточном этапе, а затем использовать полученную строку для сопоставления. Есть ли более элегантный способ сделать это?

Комментарии:

1. Я не знаю ни одного нормального движка, у которого нет расширенного модификатора. Учитывая все обстоятельства, вам нужна программа форматирования регулярных выражений, которая автоматически выполняет сжатие / расширение. Это хороший вариант regexformat.com . На следующей неделе они выходят с версией 5, которая имеет встроенное тестирование и невероятные возможности макросов.

2. Просто обратите внимание, что любой движок, поддерживающий модификаторы, обычно поддерживает их 'inline' , поэтому для расширенного режима первым символом строки регулярного выражения будет конструкция модификатора "(?x) .." . Модификаторы могут быть где угодно. Читайте о модификаторах, берегите свой мозг.

3. @sln Спасибо за комментарий. Я уже начинаю понимать, что вы имеете в виду.

4. @sln Python требует, чтобы (?x) это вставлялось в начале (за исключением пробелов). Если вы вставите его позже, поведение не определено.

Ответ №1:

Да, установив флаг re.X / re.VERBOSE :

Этот флаг позволяет вам писать регулярные выражения, которые выглядят лучше. Пробелы в шаблоне игнорируются, за исключением случаев, когда они находятся в классе символов, или когда им предшествует неэкранированная обратная косая черта, или внутри таких токенов, как *? , (?: или (?P<...> . Когда строка содержит a # , которого нет в классе символов и которому не предшествует неэкранированная обратная косая черта, все символы от крайнего левого такого # до конца строки игнорируются.

Это означает, что два следующих объекта регулярных выражений, которые соответствуют десятичному числу, функционально равны:

 a = re.compile(r"""d    # the integral part
                   .    # the decimal point
                   d *  # some fractional digits""", re.X)
b = re.compile(r"d .d*")
 

Это в значительной степени похоже на /x флаг Perl.

Вы можете управлять одним и тем же флагом в подразделе вашего шаблона в группах (?x:...) (включить) и (?-x:...) (отключить).

Комментарии:

1. Я бы также отметил, что, по крайней мере, для примера из документации, вы могли бы просто сделать каждую строку независимой строкой, и они были бы объединены вместе, что позволило бы вам использовать стандартные комментарии Python, которые, возможно, были бы более понятны для чтения.

2. @SilasRay: Я не согласен; вам придется цитировать каждый фрагмент, который вы хотите окружить пробелами. Обратите внимание, что между d и , например, есть пробел.

3. Следовательно, почему я сказал «возможно». 😉 Лично я нахожу это более понятным, но это может быть потому, что я обычно работаю с редакторами, которые имеют форматирование цветового кода, поэтому строки и комментарии выделяются как отдельные для меня более четко, если они являются настоящими комментариями / строками Python.

Ответ №2:

Чтобы добавить, встроенные модификаторы могут быть помещены в регулярное выражение, чтобы обеспечить соответствующее поведение сопоставления для данного выражения. В Python встроенные модификаторы применяются ко всему регулярному выражению и не поддерживают встроенные модификаторы отрицания, такие как (?-ismx)

 pattern = re.compile(r'''
                       (?x) 
                        d  (?# Some numbers)
                        s  (?# Whitespace)
                        d  (?# More numbers)
                      ''');
 

Обходным путем было бы импортировать модуль регулярных выражений Python, в котором встроенные модификаторы применяются к концу группы или шаблона, и их можно включить или выключить.

 import regex
pattern = regex.compile(r'(?x)  d   (?-x)[a-z] (?x)   d ', regex.V1)
 

Комментарии:

1. Учитывая re.compile() использование, видит ли движок кучу буквенных пробелов перед этим (?x) или это задним числом влияет на все регулярное выражение?