Сложность замены Regex

Я нигде не получил ответа на этот вопрос. Какова сложность выполнения сопоставления и замены Regex?

Обновлено: я работаю на питоне. Но хотелось бы знать в целом о наиболее популярных языках / инструментах (java, perl, sed).

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
13
0
6 693
8
Перейти к ответу Данный вопрос помечен как решенный

Ответы 8

Зависит от реализации. Какой язык / библиотека / класс? Это может быть лучший случай, но он будет очень специфичным для количества функций в реализации.

Ответ принят как подходящий

С чисто теоретической позиции:

Знакомая мне реализация - это создание детерминированного конечного автомата для распознавания регулярного выражения. Это делается за O (2 ^ m), m - размер регулярного выражения, с использованием стандартного алгоритма. После того, как это построено, прохождение строки через нее линейно по длине строки - O (n), n - длина строки. Замена совпадения, найденного в строке, должна быть постоянной по времени.

В целом, я полагаю, O (2 ^ m + n).

Является ли сложность по-прежнему линейной при рассмотрении возможности отслеживания с возвратом, необходимой для некоторых кванторов?

Joey 11.04.2009 18:18

Меня интересует доказательство того, что «Это делается за O (2 ^ m), m - размер регулярного выражения, с использованием стандартного алгоритма». Как вы к этому пришли?

Léo Léopold Hertz 준영 11.04.2009 18:27

Есть ли гармоничная серия по количеству срабатываний в экстремальной ситуации?

Léo Léopold Hertz 준영 16.04.2009 00:51

O (2 ^ m) на самом деле слишком пессимистично; вам не нужно создавать DFA для его запуска :)

jpalecek 20.04.2009 04:34

Вот ссылка на статью, содержащую доказательства фактов: А. В. Ахо, «Алгоритмы поиска шаблонов в строках», в Справочнике по теоретической информатике, т. А. Алгорит, Elsevier, 1990, стр. 255-300. полный текст

Dennis Golomazov 28.12.2011 13:12

Чтобы вникнуть в ответ, для построения автомата O (2 ^ m) - наихудший случай, хотя он действительно зависит от формы регулярного выражения (для очень простого, которое соответствует слову, оно находится в O ( m), используя, например, Алгоритм Кнута-Морриса-Пратта).

Вы можете обменять пространство на скорость, построив недетерминированный конечный автомат вместо DFA. Это можно пройти за линейное время. Конечно, в худшем случае для этого может потребоваться O (2 ^ m) пространства. Я ожидал, что компромисс того стоит.

Зависит от того, что вы определяете с помощью регулярного выражения. Если вы разрешаете операторы конкатенации, альтернативы и звездочки Клини, время на самом деле может быть O(m*n+m), где m - это размер регулярного выражения, а n - длина строки. Вы делаете это, создавая NFA (который является линейным в m), а затем моделируете его, поддерживая набор состояний, в которых вы находитесь, и обновляя его (в O(m)) для каждой буквы ввода.

Вещи, которые затрудняют синтаксический анализ регулярных выражений:

  • круглые скобки и обратные ссылки: захват по-прежнему в порядке с вышеупомянутым алгоритмом, хотя его сложность будет выше, поэтому это может быть недопустимым. Обратные ссылки повышают узнаваемость регулярного выражения, и его сложность хорошо
  • позитивный взгляд в будущее: это просто еще одно название для пересечения, которое повышает сложность вышеупомянутого алгоритма до O(m^2+n)
  • отрицательный прогноз: катастрофа для создания автомата (O(2^m), возможно, PSPACE-complete). Но все же должно быть возможно справиться с динамическим алгоритмом в чем-то вроде O(n^2*m).

Обратите внимание, что с конкретной реализацией все может стать лучше или хуже. Как показывает практика, простые функции должны быть достаточно быстрыми, а однозначные (например, не такие как a*a*) регулярные выражения лучше.

Другая теоретическая информация, представляющая возможный интерес.

Для ясности предположим стандартное определение регулярного выражения.

http://en.wikipedia.org/wiki/Regular_language

из теории формального языка. Практически это означает, что единственное здание материала - символы алфавита, операторы конкатенации, чередования и Замыкание Клини вместе с единичной и нулевой константами (которые появляются для теоретико-групповые соображения). Как правило, лучше не перегружать этот термин несмотря на повседневную практику языков сценариев, которая приводит к двусмысленность.

Существует конструкция NFA, которая решает проблему согласования для обычного выражение r и входной текст t во времени O (| r | | t |) и пространстве O (| r |), где | - | - функция длины. Этот алгоритм был дополнительно улучшен Майерсом.

http://doi.acm.org/10.1145/128749.128755

до временной и пространственной сложности O (| r | | t | / log | t |) с использованием автоматных списков узлов и парадигмы четырех русских. Эта парадигма, кажется, названа в честь четырех русских парней, написавших новаторскую статью, которая онлайн. Тем не менее, парадигма проиллюстрирована в этих вычислительных биологиях. конспект лекций

http://lyle.smu.edu/~saad/courses/cse8354/lectures/lecture5.pdf

Я считаю забавным называть парадигму цифрами и национальность авторов вместо их фамилий.

Проблема сопоставления для регулярных выражений с добавленными обратными ссылками: NP-полная, что доказал Ахо

http://portal.acm.org/citation.cfm?id=114877

редукцией из задачи о вершинном покрытии, которая является классической NP-полной задачей.

Чтобы детерминированно сопоставить регулярные выражения с обратными ссылками, мы могли бы использовать отслеживание с возвратом (в отличие от движка регулярных выражений Perl), чтобы отслеживать возможные подслова входного текста t, которые могут быть присвоены переменным в р. Есть только O (| t | ^ 2) подслов, которые могут быть присвоены любой переменной. в г. Если в r есть n переменных, то существует O (| t | ^ 2n) возможных задания. После того, как присвоение подстрок переменным зафиксировано, проблема сводится к простому сопоставлению регулярных выражений. Следовательно сложность наихудшего случая сопоставления регулярных выражений с обратными ссылками составляет О (| t | ^ 2n).

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

Возьмем, к примеру, символ "безразлично", отдельно от других операторы. Существует несколько полиномиальных алгоритмов, определяющих, является ли набор Шаблоны соответствуют входному тексту. Например, Кучеров и Русинович

http://dx.doi.org/10.1007/3-540-60044-2_46

определите шаблон как слово w_1 @ w_2 @ ... @ w_n, где каждый w_i - это слово (не регулярное выражение), а «@» - символ переменной длины «безразлично», не содержащийся ни в одном из w_i. Они выводят алгоритм O ((| t | + | P |) log | P |) для сопоставления набора шаблонов P с входным текстом t, где | t | - длина текста, а | P | - длина всех слов в P.

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

Увы, про Python я ни слова не сказал ... :)

Если вы после сопоставления и замены, это подразумевает группировку и обратные ссылки.

Вот пример Perl, в котором группировка и обратные ссылки могут использоваться для решения полной проблемы NP: http://perl.plover.com/NPC/NPC-3SAT.html

Это (в сочетании с некоторыми другими теоретическими лакомыми кусочками) означает, что использование регулярных выражений для сопоставления и подстановки является NP-полным.

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

Боюсь, я не понимаю, что вы имеете в виду под «решением NP-полной задачи». Из-за своей NP-полноты не существует эффективного (полиномиального времени) алгоритма для вычисления экземпляров 3-CNF-SAT. Такой алгоритм нужен для решать проблемы. Тот факт, что можно кодировать 3-CNF-SAT с помощью регулярного выражения, еще не означает, что регулярное выражение решает 3-CNF-SAT, потому что не существует алгоритма с полиномиальным временем для вычисления регулярного выражения.

user108761 04.06.2009 20:12

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

Dave 06.06.2009 10:59

В библиотеке Python re, даже если регулярное выражение скомпилировано, сложность в некоторых случаях может быть экспоненциальной (по длине строки), поскольку она не построена на DFA. Некоторые ссылки здесь, здесь или здесь.

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