2010-12-02 6 views
2

J'ai une zone de texte multiligne (textarea) que je veux vérifier a une chaîne particulière. Je tentais:RegularExpressionValidator lent dans une zone de texte multiligne (zone de texte)

<asp:RegularExpressionValidator runat="server" ControlToValidate="txtTemplate" ValidationExpression="^(.\s*)*Content(.\s*)*$" Text="content" ErrorMessage="Must contain: Content" /> 

En utilisant ^(.\s*)*$ semble passer pour un textarea. J'ai donc essayé de prendre mes critères en sandwich entre deux d'entre eux. Mais il semble bloquer à la fois IE et Chrome.

Cela devrait être simple, je pense que je le rends plus difficile que nécessaire.

Répondre

4

Si la validation est toujours en cours sur le serveur (c'est ce que runat="server" signifie, non?), La solution la plus simple est probablement d'utiliser cette regex:

(?s)^.*Content.*$ 

(?s) active le mode Singleline, ce qui permet au métacaractère . de correspondre à tous les caractères , y compris les lignes. Si vous souhaitez l'exécuter sur le client aussi bien, utilisez ceci:

^[\s\S]*Content[\s\S]*$ 

C'est parce que JavaScript n'a pas d'équivalent pour le mode Singleline (également connu sous le nom DOT_ALL, DOTALL, point-Correspondances- tous, unique ligne, ou mode /s). Il ne reconnaît pas les modificateurs en ligne tels que (?s) et (?i).

Attention aux constructions comme (.\s*)*, où une expression de quantificateurs (*, +, etc.) est enfermé dans un groupe qui est lui-même commandé par un quantificateur. Si la regex ne parvient pas à trouver une correspondance immédiatement, elle revient en arrière et essaie de faire correspondre des chemins différents (c'est-à-dire en utilisant différentes parties de la regex pour correspondre aux différentes parties de la chaîne), ce qui peut coûter très cher. Cette regex est particulièrement mauvaise car . et \s peuvent correspondre à plusieurs des mêmes caractères, ce qui augmente considérablement le nombre de chemins qu'il doit explorer avant d'abandonner.

Le phénomène est généralement connu comme catastrophic backtracking, et il se manifeste habituellement dans les cas où il n'y a aucune possibilité d'une correspondance. Je m'attendrais à ce que votre validateur fonctionne correctement lorsque la séquence Content est présente.

Par ailleurs, si vous voulez faire correspondre uniquement sur le mot complet Content, vous devez ajouter des limites de mots, comme ceci:

(?s)^.*\bContent\b.*$ 

Cela permettra d'éviter les faux positifs sur les mots comme MalContent et Contentious. \b fonctionne différemment selon les différentes saveurs de regex. Dans .NET, il est compatible Unicode sauf si vous spécifiez le mode ECMAScript.En JavaScript, il est supposé reconnaître uniquement les lettres et chiffres ASCII en tant que caractères de mot; dans la plupart des navigateurs, il le fait, mais ne le prenez pas pour acquis.

+0

Super réponse. J'ai utilisé l'option [\ s \ S] puisque je voulais qu'elle fonctionne aussi côté client (runat = "serveur" signifie que le serveur doit interpréter la balise, EnableClientScript = "false" ne l'exécuterait que sur le serveur) . – Eric

0

Je pense qu'un regex plus comme .*Content.* serait plus efficace et peut-être plus rapide. En outre, vous souhaiterez peut-être implémenter un validateur personnalisé si cela continue à être un glissement de performance, où vous utilisez JavaScript pour rechercher le texte de la chaîne.

+0

Ne fonctionne pas. La période n'attrape pas les nouvelles lignes, c'est pourquoi j'ai inclus le "\ s" (espace). Je pourrais faire un validateur personnalisé, mais c'est comme huit autres lignes de code :) – Eric

1

Essayez

[\S\s]*Content[\S\s]* 
Questions connexes