我正在使用RegExp来验证ASP.NET网页上的一些用户输入。它意味着强制构造一个密码(即8到20个长,至少一个大写字符,至少一个小写字符,至少一个数字,至少一个字符#@!$%并且不使用字母L或O(大写或小写)或数字0和1.此RegExp在我的测试人员(Expresso)和我的C#代码中工作正常。
它的外观如下:
(?-i)^(?=.{8,20})(?=.*[2-9])(?=.*[a-hj-km-np-z])(?=.*[A-HJ-KM-NP-Z])
(?=.*[#@!$%])[2-9a-hj-km-np-zA-HJ-KM-NP-Z#@!$%]*$
(为格式化添加换行符)
但是,当我运行代码时,它存在于IE6或IE7中(没有尝试过其他浏览器,因为这是一个内部应用程序而我们是微软商店),我收到一个运行时错误,说'常规中的语法错误表达'。就是这样 - 除了行号之外,错误消息中没有更多信息。
JavaScript不喜欢这个是什么?
答案 0 :(得分:5)
嗯,有两种方法可以在Javascript中定义Regex:
一个。通过Regexp对象构造函数:
var re = new RegExp("pattern","flags");
re.test(myTestString);
湾使用字符串文字:
var re = /pattern/flags;
您还应该注意JS不支持正则表达式的一些原则。有关JS中不支持的功能的非全面列表,请查看regular-expressions.info站点。
具体来说,您似乎在表达式上设置了一些标志(例如,不区分大小写的标志)。我建议你使用/i
标志(如上面的语法所示)而不是使用(?-i)
这将使您的正则表达式如下(似乎支持正向前瞻):
/^(?=.{8,20})(?=.*[2-9])(?=.*[a-hj-km-np-z])(?=.*[A-HJ-KM-NP-Z])(?=.*[#@!$%])[2-9a-hj-km-np-zA-HJ-KM-NP-Z#@!$%]*$/i;
有关此主题的非常好的文章,请查看Regular Expressions in JavaScript。
编辑(在Howard的评论之后)
如果您只是将此正则表达式模式分配给RegularExpressionValidator控件,那么您将无法设置Regex选项(例如忽略大小写)。此外,您将无法使用Javascript支持的Regex文字语法。因此,剩下的唯一选择是使您的模式本质上不区分大小写。例如,[a-h]
必须写为[A-Ha-h]
。这会让你的正则表达式啰嗦,我很遗憾地说。
Here is a solution这个问题,虽然我不能保证它的合法性。我们想到的其他一些选项可能是完全关闭客户端验证并在服务器上进行验证。这将使您可以访问System.Text.RegularExpressions.Regex
对象实现的完整正则表达式。或者,使用CustomValidator并创建自己的JS函数,该函数使用我(和其他人)建议的模式应用正则表达式匹配。
答案 1 :(得分:1)
我不熟悉C#的正则表达式语法,但这是(在开始时)
(?-i)
意味着打开不区分大小写模式修饰符?如果是这样,那就是你的问题。 Javascript不支持在表达式中指定模式修饰符。在javascript中有两种方法可以做到这一点
var re = /pattern/i
var re = new RegExp('pattern','i');
尝试其中一个,你的表达应该很开心。
答案 2 :(得分:1)
正如Cerberus所提到的,JavaScript regexp不支持(?-i)。所以,你需要摆脱它并使用/ i。需要记住的是,正则表达式语法没有标准;它在每种语言中都有所不同,因此使用.NET正则表达式引擎进行测试并不是对它如何在JavaScript中工作的有效测试。相反,请尝试查找JavaScript正则表达式的引用,例如this one。
您查找8-20个字符的匹配也无效。这将确保至少有8个字符,但它不会将字符串限制为20,因为末尾带有kleene-closure(*运算符)的字符类可以匹配提供的字符数。你想要的是用{8,20}替换最后的*,并从头开始消除它。
var re = /^(?=.*[2-9])(?=.*[a-hj-km-np-z])(?=.*[A-HJ-KM-NP-Z])(?=.*[#@!$%])[2-9a-hj-km-np-zA-HJ-KM-NP-Z#@!$%]{8,20}$/i;
另一方面,我不确定你为什么要限制密码的长度,除非有一个硬数据库限制(不应该这样,因为你不应该以纯文本形式存储密码)在数据库中,而是使用带盐的安全散列算法将它们散列到固定大小。如上所述,我认为没有理由对你允许的字符集进行如此限制。我建议更像这样的东西:
var re = /^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[#@!$%])[a-zA-Z0-9#@!$%]{8,}$/i;
另外,为什么你要禁止密码中的1,0,L和O(看起来你也试图禁止我,你忘了提及)?这将使人们很难构建好的密码,并且由于您在键入密码时从未看到密码,因此没有理由担心看起来容易混淆的字母。如果你想拥有一个更宽松的正则表达式:
var re = /^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[#@!$%]).{8,}$/i;
答案 3 :(得分:0)
您是否将正则表达式括在/ /字符中?
var regexp = /[]/;
return regexp.test();
答案 4 :(得分:0)
( - ?I)
JS Regexp中不存在。标志可以指定为“new RegExp('pattern','i')”或文字语法“/ pattern / i”。
(?=
存在于JS Regexp的modern implementations中,但在IE中是危险的buggy。 出于这个原因,JS中应该避免使用Lookahead断言。。
8到20个长,至少一个大写字符,至少一个小写字符,至少一个数字,至少一个字符#@!$%和不使用字母L或O(上部或低于)或数字0和1。
你是否 在RegExp中执行此操作,并且有将所有条件放在一个RegExp中吗?因为这些条件很容易使用多个RegExps匹配,甚至是简单的字符串匹配:
if (
s.length<8 || s.length>20 ||
s==s.toLowerCase() || s==s.toUpperCase() ||
s.indexOf('0')!=-1 || s.indexOf('1')!=-1 ||
s.toLowerCase().indexOf('l')!=-1 || s.toLowerCase().indexOf('o')!=-1 ||
(s.indexOf('#')==-1 && s.indexOf('@')==-1 && s.indexOf('!')==-1 && s.indexOf('%')==-1 && s.indexOf('%')==-1)
)
alert('Bad password!');
(如果是最终用户BTW,这些是非常残忍且无用的密码规则!)
答案 5 :(得分:0)
我会使用这个正则表达式:
/(?=[^2-9]*[2-9])(?=[^a-hj-km-np-z]*[a-hj-km-np-z])(?=[^A-HJ-KM-NP-Z]*[A-HJ-KM-NP-Z])(?=[^#@!$%]*[#@!$%])^[2-9a-hj-km-np-zA-HJ-KM-NP-Z#@!$%]{8,}$/
[^
a-z
]*[
a-z
]
将确保匹配为尽早做出,而不是扩展.*
并进行回溯。
答案 6 :(得分:0)
(?-i)
应该会将不区分大小写 关闭 。似乎每个人都假设你试图将它转换为,但那将是(?i)
。无论如何,你不希望它不区分大小写,因为你需要确保有大写和小写字母。由于区分大小写的匹配是默认的,因此即使在支持内联修饰符的那些风格(如.NET)中,使用(?-i)
前缀正则表也是毫无意义的。