Длинные регулярные выражения хуже коротких? - PullRequest
2 голосов
/ 22 сентября 2019

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

например:

struc_enum = OrGroup("struct", "enum")
whitespace = TAB_SPACE.at_least(1)

в результате:

(?:struct|enum)
[ \t]+

в этом случае использование псевдонимов Python не дает больших преимуществ, но тогда я могу сделать следующее:

valid_name = r"\b" + Group(ALPHA, ALPHANUMERIC.repeated())
struc_enum = OrGroup("struct", "enum")
typed_name = (struc_enum + whitespace).optional() + valid_name + whitespace + valid_name.captured()

и вот что отображает print(typed_name):

(?:(?:(?:struct|enum)[ \t]+)?\b[a-zA-Z][a-zA-Z\d]*[ \t]+(\b[a-zA-Z][a-zA-Z\d]*))

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

(?:(func)[\s]+([a-zA-Z_]+[a-zA-Z\d_]*)[\s]*\([\s]*(?:[a-zA-Z_]+[a-zA-Z\d_]*(?:[\s]*[a-zA-Z_]+[a-zA-Z\d_]*[*]{,2})?(?:[\s]*,[\s]*[a-zA-Z_]+[a-zA-Z\d_]*(?:[\s]*[a-zA-Z_]+[a-zA-Z\d_]*[*]{,2})?)*[\s]*)?\))

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

func myfunc(asd asd*, asd*, asdasd)
func do_foo01(type arg1, int arg2)

С enougПри терпении человек может создать эквивалентное выражение, но, вероятно, намного короче, что поднимает вопрос.Большие регулярные выражения хуже или лучше эквивалентных более коротких в терминах вычислительных затрат?В какой момент мы можем считать регулярные выражения слишком большими?

Ответы [ 2 ]

1 голос
/ 22 сентября 2019

Поскольку исходная проблема, которую вы решили решить, состоит в том, что длинные регулярные выражения трудно читать, вы можете рассмотреть расширенные (подробные) регулярные выражения.Расширенные регулярные выражения допускают пробелы и комментарии, что может значительно облегчить чтение регулярного выражения.

Сравните это регулярное выражение:

charref = re.compile("&#(0[0-7]+"
                     "|[0-9]+"
                     "|x[0-9a-fA-F]+);")

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

charref = re.compile(r"""
 &[#]                # Start of a numeric entity reference
 (
     0[0-7]+         # Octal form
   | [0-9]+          # Decimal form
   | x[0-9a-fA-F]+   # Hexadecimal form
 )
 ;                   # Trailing semicolon
""", re.VERBOSE)

Пример взят из Регулярное выражение HOWTO

0 голосов
/ 22 сентября 2019

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

Мы почти никогда не нуждаемся в для использования регулярных выражений;мы могли бы разобрать каждую строку и написать свои собственные операции синтаксического анализа, используя starts_with, if s и т. д. Но синтаксис регулярных выражений - это зрелая , мощная система, которая позволяет нам кратко выражают определенные виды логики.

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

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

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

...