0

任何人都可以解释下面的正则表达式,甚至在我加入之前,它已经在我的应用程序中使用了很长时间,而且我对正则表达式非常陌生。

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

据我所理解

此正则表达式将验证 - 至少 6 个字符到最多 10 个字符 - 将转义 ^ 和 $ 等字符

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

4

4 回答 4

7
^.*(?=.{6,10})(?=.*[a-zA-Z].*[a-zA-Z].*[a-zA-Z].*[a-zA-Z])(?=.*\d.*\d).*$
  • ^被称为“锚”。这基本上意味着任何后续文本都必须紧跟在“输入开始”之后。所以^B会匹配“B”而不是“AB”,因为第二个“B”不是第一个字符。

  • .*匹配 0 个或多个字符 - 除换行符以外的任何字符(默认情况下)。这就是所谓的贪婪量词 - 正则表达式引擎会将所有字符匹配(“消耗”)到输入的末尾(或行尾),然后向后处理表达式的其余部分(它“仅在必须时放弃”字符)。在正则表达式中,一旦一个字符被“匹配”,表达式的任何其他部分都不能再次“匹配”它(除了零宽度环视,接下来会出现)。

  • (?=.{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”和“e”不能包含在匹配中。

笔记

这看起来像一个密码验证正则表达式。如果是,请注意它已损坏。开头和结尾将.*允许密码任意长于 10 个字符。它也可以重写为更短一些。我相信以下内容将是可接受的(并且更具可读性)的替代品:

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

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

于 2013-01-17T17:25:01.023 回答
2

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

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

第一个.*是多余的,因为其余的都是零宽度断言,以任何字符开头,.最后.*

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

(?=.*[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}.

以下正则表达式等效于您的原始正则表达式。但是,我真的怀疑您当前的版本,并且您的正则表达式的等效重写可以满足您的要求:

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

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

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

回顾

  • 最小长度 = 6
  • 最大长度没有限制
  • 至少4个英文字母,小写或大写
  • 至少2位数0-9
于 2013-01-17T17:45:32.177 回答
0

正则解释

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

  • ^: 匹配输入字符串的开头

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

  • *: 匹配前一个符号 0 次或更多次

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

  • [a-zA-Z]: 匹配and之间的所有字符azand之间A的所有字符Z

  • \d: 匹配一个数字。

  • $: 匹配输入的结尾。

我认为这对于您发布的正则表达式中的所有符号都是如此

于 2013-01-17T17:23:53.533 回答
0

对于您的正则表达式请求,您将使用以下内容:

^(?=.{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)。以下是接受的(您可以根据需要进行修改):

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

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

于 2013-01-17T17:51:53.073 回答