Depuis que j'étudie pour mon cours universitaire de langues officielles, je suis tombé sur ces messages fascinants ( One Two ) qui décrivent comment trouver un nombre premier à l'aide d'une expression rationnelle . Comme je l'ai dit, une expression rationnelle , pas une expression régulière . Puisqu'une expression régulière peut correspondre à des chaînes calculées par un automate à états finis et que la recherche d'un nombre premier ne peut pas être effectuée par un FSA, l'expression rationnelle affichée dans le billet de blog n'est pas entièrement une expression régulière, car elle effectue un retour en arrière pour correspondre à la chaîne.
Comme je n'ai jamais vraiment utilisé d'expression régulière, maintenant, ma question:
Comment puis-je reconnaître immédiatement une expression rationnelle à partir d'une "vraie" expression régulière simplement en la regardant?
Définitions: Par expression régulière, je me réfère à la notion telle que définie dans les langages formels. Par regexp, je veux dire la notion supportée par les langages de programmation modernes; la syntaxe regexp contient souvent des fonctionnalités supplémentaires, telles que les références arrières. Les expressions régulières telles que vues dans les langages de programmation sont strictement plus puissantes que les expressions régulières de style de langage formel.
la source
Réponses:
tl; dr backrefs.
Dès qu'il y a un
\1
(ou n'importe quel nombre qui n'est pas utilisé pour échapper à l'unicode) dans l'expression régulière, ce n'est pas une expression régulière.Backrefs vous permet de faire correspondre
(a+)b\1
ce qui correspond à n foisa
suivi de b suivi de n foisa
pour n> 1. Ce n'est pas une langue régulière (c'est l'enfant affiche d'une langue non régulière).Il est nécessaire et presque suffisant que le backref fasse référence à un groupe qui contient une expression rationnelle qui correspond à une chaîne arbitrairement longue ou qu'il contient un
*
ou+
. La seule exception (que j'ai trouvée) d'une expression rationnelle de la forme(A)B\1
où A est un langage fini (pourrait être remplacée par une énumération de tous les mots qui les accepte). Vous pouvez le convertir enword1+Bword1|word2+Bword2
etc. car A est fini.Les groupes de recherche ne suppriment pas la régularité de l'expression régulière.
A(?=B)C
est la section transversale des expressions rationnellesAB.*
etAC
et la section transversale de 2 langues régulières est régulière. L'anticipation négative est similaire, sauf en utilisant le complément deB.*
(les compléments de langues régulières étant réguliers). Lookbehind est exactement le même queA(?<=B)C
la coupe transversale deAC
et.*BC
.la source
(a)\1
que, tout en utilisant un backref, est équivalentaa
et donc trivialement régulier. Je me demande également si les assertions d'anticipation peuvent utiliser pour reconnaître les langues non régulières.(a)\1
n'est pas une expression régulière, mais reconnaît un langage régulier.