En jouant avec des expressions régulières, en particulier la correspondance équilibrée de la saveur .NET, je suis arrivé à un point où je me suis rendu compte que je ne comprenais pas le fonctionnement interne du moteur aussi bien que je le pensais. J'apprécierais n'importe quelle contribution sur pourquoi mes modèles se comportent comme ils le font! Mais poing ...Comment les conditions dans les groupes lookaround fonctionnent-elles dans .NET regex?
Avertissement: Cette question est purement théorique, et tout résultat obtenu ici ne sera jamais utilisé, ou modifié et utilisé dans le code de production pour analyser HTML. Déjà. Je promets. Je crains le poney. =)
Maintenant à mon problème. Je vais essayer de faire correspondre la lettre A
, si elle n'est pas précédée d'un #
. Pour démontrer, je vais toujours utiliser la chaîne ..A..#..A..
. Ici, le premier A
doit correspondre. Bien sûr, c'est une tâche assez facile en utilisant "A(?<!^.*#.*)"
, mais je souhaite utiliser des conditionnels ici, car ils peuvent être utilisés pour des appariements équilibrés et d'autres choses sympas.
Ce que j'ai essayé est
"A(?<=^(#(?<q>)|[^#])*(?(q)(?!)))"
La façon dont je l'interprète est: lorsque le moteur encounteres « A », il remonte au début de la chaîne, et pour chaque caractère ajouter une correspondance vide le groupe de capture q si le caractère est un #. Ensuite, il devrait échouer si q contient une correspondance. Ce que je ne comprends pas, c'est pourquoi cette expression correspond à As dans mon exemple de chaîne.
Lorsque je supprime simplement le lookbehind et correspondre à la chaîne entière, cela fonctionne:
"^(#(?<q>)|[^#])*(?(q)(?!))A"
correspond à la chaîne entière jusqu'à la première A, même si le quantificateur du premier groupe est gourmand. L'insertion d'un '#' au début provoquera également l'échec de la correspondance (comme souhaité). Donc, comment regarder les groupes autour, les groupes de capture nommés en leur sein et les conditionnels jouent ensemble?
Merci!
Modifier: Ce problème peut être vu plus facilement dans (?<=(?<q>)(?(q)(?!))).
, qui ne devrait correspondre à aucun caractère, mais correspond à tout.
+1 et je ne suis arrivé à deuxième alinéa jusqu'à présent./Ok, lis le tout, mais tant pis c'est très spécifique à C# et je ne peux pas contribuer ... ENCORE! Question favorisée et mise en signet! – polygenelubricants
@polygenelubricants: Hehe, merci! =) – Jens