Технический ответ: традиционно egrep
внутренне использовал детерминированный конечный автомат (DFA), а grep
использовал недетерминированный конечный автомат (NFA). В наши дни GNU grep
и egrep
используют гибридный подход NFA/DFA.
В соответствии с книгой Фридла « Освоение регулярных выражений», чтобы выяснить, есть ли у вашего egrep
(например) механизм NFA или есть DFA, попробуйте:
echo =XX========================================= | egrep 'X(.+)+X'
Фрейдл (с.147) говорит:
Если это займет много времени, чтобы закончить, это NFA ... Если он заканчивается быстро, это либо DFA, либо NFA с некоторой продвинутой оптимизацией. Отображается ли предупреждающее сообщение о превышении стека или длинном совпадении? Если так, то это NFA.
Фридл описывает механизм NFA как "ориентированный на регулярные выражения", а DFA - как "ориентированный на текст". Детали различия описаны со стр. 153 его книги.
Следствием этого является то, что есть некоторые комбинации шаблон / текст, которые быстрее сопоставляются с DFA, а некоторые - быстрее с NFA. Кроме того, способ написания регулярного выражения для NFA может существенно повлиять на скорость сопоставления. Зачастую DFA будет быстрее, но DFA не поддерживают ленивое сопоставление, в некоторых случаях они совпадают, они не могут выполнять обратные выражения или обратные ссылки, и в них отсутствуют некоторые другие функции по сравнению с NFA.
Согласно Freidl, GNU grep
использует DFA, когда это возможно, и возвращается к NFA, когда используются обратные ссылки.