Скажем, у вас есть документ с написанным эссе. Вы хотите разобрать это эссе, чтобы выбрать только определенные слова. Круто.
Является ли использование регулярного выражения быстрее, чем разбор файла строка за строкой и слово за словом в поисках совпадения? Если так, как это работает? Как ты можешь идти быстрее, чем смотреть на каждое слово?
regular-expressions
Lazer
источник
источник
Ответы:
Взгляните на теорию автоматов
Короче говоря, каждое регулярное выражение имеет эквивалентный конечный автомат и может быть скомпилировано и оптимизировано до конечного автомата. Соответствующие алгоритмы можно найти во многих сборниках. Эти алгоритмы используются программами Unix, такими как awk и grep.
Однако большинство современных языков программирования (Perl, Python, Ruby, Java (и языки на основе JVM), C #) не используют этот подход. Они используют рекурсивный подход обратного отслеживания, который компилирует регулярное выражение в дерево или последовательность конструкций, представляющих различные подчасти регулярного выражения. Большинство современных синтаксисов «регулярных выражений» предлагают обратные ссылки, которые находятся за пределами группы регулярных языков (они не имеют представления в конечных автоматах), которые тривиально реализуются в рекурсивном подходе обратного отслеживания.
Оптимизация обычно дает более эффективный конечный автомат. Например: рассмотрим aaaab | aaaac | aaaad, обычный программист может получить простую, но менее эффективную реализацию поиска (сравнивая три строки отдельно) прямо за десять минут; но, понимая, что это эквивалентно aaaa [bcd], лучший поиск можно выполнить, выполнив поиск первых четырех «a», а затем проверив 5-й символ по [b, c, d]. Процесс оптимизации был одним из моих домашних заданий компилятора много лет назад, поэтому я предполагаю, что он также используется в большинстве современных движков регулярных выражений.
С другой стороны, конечные автоматы имеют некоторое преимущество, когда они принимают строки, потому что они используют больше места по сравнению с «тривиальной реализацией». Рассмотрим программу для отмены кавычек в строках SQL, а именно: 1) начинается и заканчивается одинарными кавычками; 2) одинарные кавычки экранируются двумя последовательными одинарными кавычками. Итак: input ['a' ''] должен давать output [a ']. С помощью конечного автомата последовательные одинарные кавычки обрабатываются двумя состояниями. Эти два состояния служат для запоминания истории ввода так, что каждый входной символ обрабатывается ровно только один раз, как показано ниже:
Поэтому, на мой взгляд, регулярное выражение может быть медленнее в некоторых тривиальных случаях, но обычно быстрее, чем алгоритм поиска, созданный вручную, учитывая тот факт, что оптимизация не может быть надежно выполнена человеком.
(Даже в таких тривиальных случаях, как поиск строки, интеллектуальный механизм может распознать один путь на карте состояний и свести эту часть к простому сравнению строк и избежать управления состояниями.)
Конкретный движок из фреймворка / библиотеки может быть медленным, потому что движок делает кучу других вещей, которые программисту обычно не нужны. Пример: класс Regex в .NET создает несколько объектов, включая Match, Groups и Captures.
источник
aaaab|aaaac|aaaad
противaaaa[bcd]
. Стоит явно указать, что эти два математически эквивалентны и создают один и тот же DFA, что дает программистам больше свободы для представления регулярного выражения таким образом, который имеет смысл (не то, что это обычная практика, но ... знаете). ..Регулярные выражения выглядят просто быстро, потому что у вас быстрые компьютеры.
Еще в 1980-х годах, когда 1 MIPS был быстрым компьютером, регулярные выражения были довольно большой областью беспокойства, беспокойства и исследований, потому что они были медленными, уродливыми и требовали большого количества вычислений. Разумная разработка алгоритмов последовала и помогла - но для всех практических целей в наши дни вы видите чудо быстрых машин, покрывающих трещины.
источник
Почему вы думаете, что они быстрее, чем поиск документа?
Есть несколько трюков, которые вы можете сделать, например. если вы ищете 10-буквенное слово, начинающееся с A и заканчивающееся на B, тогда, если вы найдете A, а позиция 9 далее - это не B, вы можете пропустить некоторые из них. см. алгоритм Кнута – Морриса – Пратта
источник
Что делает регулярное выражение быстрым?
На самом деле это не так. Не так много. Просто они не достаточно медленные, чтобы большинство из нас это заметили. В прежние медленные дни это было намного более заметно.
Они также не подходящий инструмент для каждой работы - молоток .
источник
RegEx сравнительно быстрее кода, который вы можете написать, потому что большинство библиотек - это результат того, что многие разработчики потратили много лет на их оптимизацию, чтобы выжать все возможное. Для одного человека трудно продублировать его в своем поисковом коде.
источник
Ваша основная предпосылка неверна.
Регулярные выражения не всегда быстрее простого поиска. Все зависит от контекста. Это зависит от сложности выражения, длины искомого документа и множества факторов.
То, что происходит, - то, что регулярное выражение будет скомпилировано в простой синтаксический анализатор (который занимает время). Таким образом, если документ небольшой, это дополнительное время перевесит любое преимущество. Также, если выражение простое, то регулярное выражение не даст вам никакого преимущества.
Если выражение сложное и документ достаточно большой, вы можете получить некоторую выгоду. То, насколько это важно, чтобы регулярные выражения были быстрее, будет зависеть от того, сколько усилий вы хотите приложить к поиску (также регулярные выражения могут иметь некоторые оптимизации, которые библиотека могла бы обеспечить, о которых вы сами бы не подумали).
Я пытаюсь сказать, что нет обобщенного, общего ответа. Если у вас есть конкретное выражение (и известный размер документа), то вы можете сказать, получить ответ да / нет о том, будет ли выражение быстрее простого поиска (и почему).
Настоящее преимущество регулярных выражений заключается в том, что, как только вы поймете, как их писать, вы сможете выразить сложный поиск в краткой форме. Поскольку это обобщенная форма, вы можете создавать инструменты, которые позволяют выполнять поиск таким способом, который полезен в общем случае; обычно он выполняется по крайней мере так же быстро, как и простой поиск (для документов минимального размера; для документов меньшего размера это не имеет значения, поскольку, даже если он медленнее, он все еще достаточно быстр).
источник
Вполне вероятно, что в некоторых языках высокого уровня (возможно, javascript) использование библиотеки регулярных выражений, реализованной на языке низкого уровня (возможно, C), будет быстрее, чем написание логики синтаксического анализатора на языке высокого уровня.
Вероятно - я понятия не имею, так ли это на самом деле.
источник