解释一下上面提到的正则表达式

本文关键字:正则表达式 一下 解释 | 更新日期: 2023-09-27 17:54:10

谁能解释一下下面的正则表达式,这已经在我的应用程序中使用了很长时间,甚至在我加入之前,我对正则表达式很陌生。

/^.*(?=.{6,10})(?=.*[a-zA-Z].*[a-zA-Z].*[a-zA-Z].*[a-zA-Z])(?=.*'d.*'d).*$/ 

据我所知

这个正则表达式将被验证-长度为6 ~ 10个字符-将转义像^和$

这样的字符

也,我的基本需求是我想要一个至少6个字符的正则表达式,其中1个字符是数字,另一个是特殊字符。

解释一下上面提到的正则表达式

^.*(?=.{6,10})(?=.*[a-zA-Z].*[a-zA-Z].*[a-zA-Z].*[a-zA-Z])(?=.*'d.*'d).*$
  • ^称为"锚"。它基本上意味着任何后面的文本必须紧接在"输入的开始"之后。因此^B将匹配"B"但不匹配"AB",因为第二个"B"不是第一个字符。

  • .*匹配0个或更多字符-任何字符,除了换行符(默认情况下)。这就是所谓的贪婪量词- regex引擎将匹配("消耗")所有字符到输入的末尾(或行尾),然后向后工作到表达式的其余部分(它只在必须时"放弃"字符)。在正则表达式中,一旦一个字符被"匹配",表达式的其他部分就不能再"匹配"它了(除了零宽度的遍历,这是接下来的)。

  • (?=.{6,10})是一个前瞻锚,它匹配输入中的位置。它在输入中找到一个有6到10个字符的地方,但它不会"消耗"这些字符,这意味着下面的表达式可以自由地匹配它们。

  • (?=.*[a-zA-Z].*[a-zA-Z].*[a-zA-Z].*[a-zA-Z])是另一个超前锚。它匹配以下文本中包含四个字母([a-zA-Z]匹配一个小写或大写字母)的位置,但它们之间可以有任意数量的其他字符(包括零字符)。例如:"++a5b---C@D"将匹配。同样,作为锚点,它并不实际"消耗"匹配的字符—它只在文本中查找与后面的字符匹配的位置。

  • (?=.*'d.*'d)另一个展望。这将匹配后面跟着两个数字的位置(中间有任意数量的其他字符)。

  • .*已经覆盖了这个

  • $这是另一种匹配输入结束(或行结束-换行符之前的位置)的锚。它表示前面的表达式必须匹配字符串末尾的字符。当^$一起使用时,这意味着必须匹配整个输入(而不仅仅是部分输入)。因此,/bcd/将匹配"abcde",但/^bcd$/将不匹配"abcde",因为"a"answers"e"不能包含在匹配中。

注意

这看起来像一个密码验证正则表达式。如果是,请注意它坏了。开头和结尾的.*将允许密码任意超过10个字符。它也可以改写得短一点。我相信下面是一个可以接受的(并且可读性更好的)替代:

^(?=(.*[a-zA-Z]){4})(?=(.*'d){2}).{6,10}$

感谢@nhahtdh指出了实现字符长度限制的正确方法。

查看Cyborgx37的语法解释答案。我将对正则表达式的含义做一些解释。

^.*(?=.{6,10})(?=.*[a-zA-Z].*[a-zA-Z].*[a-zA-Z].*[a-zA-Z])(?=.*'d.*'d).*$

第一个.*是多余的,因为其余的都是零宽度断言,以任意字符.开头,以.*结尾。

由于断言(?=.{6,10}), regex将匹配至少6个字符。但是,正则表达式可以匹配的字符串的字符数没有上限。这是因为末尾的.*(前面的.*也有贡献)。

(?=.*[a-zA-Z].*[a-zA-Z].*[a-zA-Z].*[a-zA-Z])部分断言至少有4个英文字母字符(大写或小写)。(?=.*'d.*'d)断言至少有2位数字(0-9)。由于[a-zA-Z]'d是不相交的集合,这两个条件的结合使得(?=.{6,10})是冗余的。

.*[a-zA-Z].*[a-zA-Z].*[a-zA-Z].*[a-zA-Z]的语法也是不必要的冗长。可以使用重复来缩短:(?:.*[a-zA-Z]){4} .

下面的正则表达式等价于原始的正则表达式。然而,我真的怀疑你当前的regex,这个等价的regex重写做你想要的:

^(?=(?:.*[a-zA-Z]){4})(?=(?:.*'d){2}).*$

在长度上更明确,因为清晰总是更好。意思是保持不变:

^(?=(?:.*[a-zA-Z]){4})(?=(?:.*'d){2}).{6,}$

回顾:

  • 最小长度= 6
  • 不限制最大长度
  • 至少4个英文字母,小写或大写
  • 至少2位0-9

REGEXPLANATION

  • /.../:斜杠通常用来表示定义正则表达式的区域

  • ^:匹配输入字符串

  • .:这可以匹配任何字符

  • *:匹配前一个符号0次或以上

  • .{6,10}:匹配.(任何字符)6到10次

  • [a-zA-Z]:匹配az之间以及AZ之间的所有字符

  • 'd:匹配数字

  • $:匹配输入结束

我认为这只是做它所有的符号在你张贴的regex

对于你的regex请求,这里是你会使用的:

^(?=.{6,}$)(?=.*?'d)(?=.*?[!@#$%&*()+_=?'^-]).*

它已经为你展开了:

^          // Anchor the beginning of the string (password).
(?=.{6,}$) // Look ahead: Six or more characters, then the end of the string.
(?=.*?'d)  // Look ahead: Anything, then a single digit.
(?=.*?[!@#$%&*()+_=?'^-]) // Look ahead: Anything, and a special character.
.*         // Passes our look aheads, let's consume the entire string.

可以看到,特殊字符必须显式定义,因为它们没有保留的速记符号(如'w's'd)。以下是被接受的(你可以根据自己的意愿修改):

!, @, #, $, %, ^, &, *, (, ), -, +, _, =, ?

理解regex向前看的关键是要记住它们不会移动解析器的位置。这意味着(?=...)将在最后一个模式匹配之后开始查看第一个字符,随后的(?=...)也将向前查看。