RegularExpressionValidator在多行文本框(textarea)上变慢

时间:2010-12-02 16:27:08

标签: asp.net regex validation

我想要验证的多行文本框(textarea)中有一个特定的字符串。我在努力:

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

使用^(.\s*)*$似乎传递了textarea。所以我试图将我的标准夹在其中两个之间。但它似乎锁定了IE和Chrome。

这应该很简单,我认为我使它变得比它需要的更难。

3 个答案:

答案 0 :(得分:4)

如果总是在服务器上进行验证(这是runat="server"的意思,不是吗?),最简单的解决方案可能就是使用这个正则表达式:

(?s)^.*Content.*$

(?s)启用Singleline模式,允许.元字符匹配所有字符,包括换行符。如果您希望它也在客户端上运行,请使用:

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

这是因为JavaScript没有Singleline模式的等效项(也称为DOT_ALLDOTALL点匹配所有单一行/s模式)。它也无法识别内联修饰符,例如(?s)(?i)

注意像(.\s*)*这样的结构,其中带有量词(*+等)的表达式包含在一个由量词控制的组中。如果正则表达式无法立即实现匹配,则它返回并尝试通过不同路径匹配(即,通过使用正则表达式的不同部分来匹配字符串的不同部分),这可能在性能方面变得非常昂贵。这个正则表达式特别糟糕,因为.\s可以匹配许多相同的字符,这大大增加了它在放弃之前必须探索的路径数量。

这种现象通常被称为catastrophic backtracking,它通常表现在不可能匹配的情况下。当序列Content存在时,我希望你的验证器能正常工作。

顺便说一句,如果您只想匹配完整的单词Content,则应添加单词边界,如下所示:

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

这样可以防止MalContentContentious等字词出现误报。 \b在不同的正则表达式中的工作方式不同。在.NET中,除非您指定ECMAScript模式,否则它具有Unicode感知功能。在JavaScript中,它应该只识别 ASCII 字母和数字作为单词字符;它在大多数浏览器中都有,但不要把它视为理所当然。

答案 1 :(得分:1)

尝试

[\S\s]*Content[\S\s]*

答案 2 :(得分:0)

我认为更像.*Content.*的正则表达式会更有效,也可能更快。此外,如果这仍然是性能阻力,您可能希望实现自定义验证器,您可以使用JavaScript在文本中搜索字符串。