Comment ça marche?
Jetez un œil à la théorie des automates
En bref, chaque expression régulière a un automate fini équivalent et peut être compilée et optimisée en un automate fini. Les algorithmes impliqués peuvent être trouvés dans de nombreux livres de compilation. Ces algorithmes sont utilisés par des programmes Unix comme awk et grep.
Cependant, la plupart des langages de programmation modernes (Perl, Python, Ruby, Java (et langages basés sur JVM), C #) n'utilisent pas cette approche. Ils utilisent une approche de retour en arrière récursif, qui compile une expression régulière dans un arbre ou une séquence de constructions représentant divers sous-morceaux de l'expression régulière. La plupart des syntaxes "d'expression régulière" modernes offrent des références arrières qui sont en dehors du groupe des langages réguliers (elles n'ont aucune représentation dans les automates finis), qui sont trivialement implémentables dans une approche de retour arrière récursif.
L'optimisation donne généralement une machine d'état plus efficace. Par exemple: considérez aaaab | aaaac | aaaad, un programmeur normal peut obtenir une implémentation de recherche simple mais moins efficace (en comparant trois chaînes séparément) directement en dix minutes; mais en réalisant que cela équivaut à aaaa [bcd], une meilleure recherche peut être effectuée en recherchant les quatre premiers «a» puis en testant le 5ème caractère par rapport à [b, c, d]. Le processus d'optimisation était l'un de mes travaux à domicile pour le compilateur il y a de nombreuses années, donc je suppose qu'il se trouve également dans la plupart des moteurs d'expression régulière modernes.
D'un autre côté, les machines à états ont un certain avantage lorsqu'elles acceptent des chaînes car elles utilisent plus d'espace par rapport à une "implémentation triviale". Considérons un programme pour annuler l'échappement des citations sur les chaînes SQL, c'est-à-dire: 1) commence et se termine par des guillemets simples; 2) les guillemets simples sont échappés par deux guillemets simples consécutifs. Donc: l'entrée ['a' ''] devrait donner la sortie [a ']. Avec une machine à états, les guillemets simples consécutifs sont gérés par deux états. Ces deux états servent à se souvenir de l'historique d'entrée de telle sorte que chaque caractère d'entrée soit traité exactement une seule fois, comme illustré ci-dessous:
...
S1->'->S2
S1->*->S1, output *, * can be any other character
S2->'->S1, output '
S2->*->END, end the current string
Donc, à mon avis, l'expression régulière peut être plus lente dans certains cas triviaux, mais généralement plus rapide qu'un algorithme de recherche conçu manuellement, étant donné que l'optimisation ne peut pas être effectuée de manière fiable par l'homme.
(Même dans des cas triviaux comme la recherche d'une chaîne, un moteur intelligent peut reconnaître le chemin unique dans la carte d'état et réduire cette partie à une simple comparaison de chaînes et éviter de gérer les états.)
Un moteur particulier d'un framework / bibliothèque peut être lent car le moteur fait un tas d'autres choses dont un programmeur n'a généralement pas besoin. Exemple: la classe Regex dans .NET crée un tas d'objets dont Match, Groupes et Captures.