2010-07-26 6 views
2

Je veux accepter une expression régulière arbitraire de l'utilisateur et l'ancrer des deux côtés afin de forcer une correspondance complète (^<user's-regex>$) mais je ne sais pas si je dois prendre en compte le fait que l'utilisateur peut avoir déjà ancré son regex. Il semble que Perl, C++, .NET et JavaScript autorisent double ancrage multiple.Double ancrage des expressions régulières

"hello" =~ /^h/ # true 
"hello" =~ /^^h/ # true 
"hello" =~ /^^^h/ # true 
"hello" =~ /e/ # true 
"hello" =~ /^e/ # false 
"hello" =~ /^^e/ # false 

Est-ce que quelqu'un sait si cela est spécifié pour fonctionner de cette façon? Puis-je dépendre de ce comportement ou est-ce un accident susceptible de changer dans le futur?


Edit: La raison pour laquelle nous avons besoin est que nous utilisons est la regex de VBScript (de COM), nous utilisons match mais cela retourne tous les matches il est donc beaucoup plus lent pour correspondre à la chaîne abc-.*a.* qu'à ^.*a.*$. En utilisant l'ancrage comme suggéré par @Tim nous accélérons les correspondances (pour les chaînes longues) de plus d'un facteur de 12.

+0

Pourquoi avez-vous besoin de cela? – SilentGhost

Répondre

4

Vous pouvez dépendre de ce comportement. Le moteur regex ne dérange pas d'affirmer la même chose une fois, deux fois, ou une centaine de fois de suite.

Cependant, au lieu de simplement ajouter des ancres autour du regex, vous devez également ajouter un groupe non-capture autour:

^(?: - utilisateur regex - )$ ou, de préférence, si votre goût regex permet ceci: \A(?: - utilisateur regex - )\Z

Sinon, vous allez trébucher si l'utilisateur utilise l'alternance dans son regex. Comparez:

user regex:   hello|bye 
anchored regex:  ^hello|bye$  // alternation now affects anchors 
correctly anchored: ^(?:hello|bye)$ 
+0

Je suis en train de mettre à jour la question avec la motivation, merci votre réponse a été très utile. – Motti