2014-09-30 65 views
3

我试图在一个正则表达式中包含两个积极的lookaheads。以下是我正在处理的问题。JavaScript正则表达式中的多个积极lookaheads的语法

(?=[a-zA-Z])(?=[0-9])[a-zA-Z0-9]{0,20} 

这就是我想要匹配:

  • 0-20个字符
  • 一个或多个字母的任何地方
  • 一个或多个号码的任何地方
  • 只有字母和数字允许

当我这样做只有一个看前进,它的工作原理,但只要我添加另一个,它就会中断。两个lookahead的正确语法是什么?

+2

这个怎么样'(?=。* [A-ZA-Z])(?=。* [0-9]) [A-ZA-Z0-9] {0,20}'? – revo 2014-09-30 20:19:01

+0

谢谢!这很奇妙! – Qaz 2014-09-30 20:21:33

+0

注意,不允许使用下划线。您需要'[a-zA-Z0-9 _] {0,20}',它与'\ w {0,20}'同义。 – Sam 2014-09-30 20:22:01

回答

6

Lookaheads就像漫游!你以不满足的第一位限制了相貌。因此,使用贪婪的.*(或懒惰)量词将允许向前查找每个断言。

由于@AlexR在评论中提到我修改正则表达式一点点:

(?=.*[a-zA-Z])(?=.*[0-9])[a-zA-Z0-9_]{0,20}$ 

顺便说一句,你忘了匹配下划线,这是我补充道。

1

当输入过长时,会出现@revos回答问题:A会通过预测和最终检查。固定版本或者检查结束字符串^$或使用可变长度环视(或两者):

^(?=.{0,19}[a-zA-Z])(?=.{0,19}[0-9])[a-zA-Z0-9]{0,20}$ // (1), (1*) without^
^(?=.*[a-zA-Z])(?=.*[0-9])[a-zA-Z0-9]{0,20}$ 
(?=.{0,19}[a-zA-Z])(?=.{0,19}[0-9])[a-zA-Z0-9]{0,20} // (2) 

只有后者将允许指定的字符串周围的文本。省略前变种^将允许密码为前缀,即

Input   : "Password1 = ASDF0123" 
Matches with (1) : none 
Matches with (1*): "ASDF0123" 
Matches with (2) : "Password1", "ASDF0123" 
+0

提出一个非常有趣的案例。因为我将在表单中使用它,所以我可以为输入标记添加maxlength =“20”属性。没有这个,我不会意识到我需要这个。 – Qaz 2014-09-30 20:44:34

+0

@Qaz我仍然会推荐使用更严格的正则表达式,因为像FireBug这样的工具允许编辑客户端,所以您永远无法确定您的表单POST(或GET)是否理智,因为它受控于您的(可能是恶意的)客户端。 – AlexR 2014-09-30 20:53:07

+0

无论我如何确定正则表达式,在客户端编辑它都非常容易 - 我正确地将它放在HTML中! ()不过,别担心。这只是为了用户的利益,所以他们知道他们的密码是否符合规则。我会在客户端进行认真的检查。也不要担心密码规则的不安全程度;这不是生产。 – Qaz 2014-09-30 21:03:17