我对Regex很新,只是刚开始在学校学习它。我得到了我的第一份任务,并且相当顺利。
让我解释一下,我的代码是有道理的......
该任务使我的.NET Regex Tester通过文本搜索密码。
这些密码不能包含任何空格(所以我使用\S
)不能以数字或下划线开头,因此我使用了(?m:^([^_|^0-9]{1})
不能以两个不同的角色结束
(?<finalTwo>(?i:\S{1}))(?i:\<finalTwo>)
必须包含至少一位数字,所以我使用了一个前瞻。 现在,问题在于,代码现在非常混乱。
(?=.*\d)(?m:^([^_|^0-9]{1})(\S*)(?<finalTwo>(?i:\S{1}))(?i:\<finalTwo>))
我还要补充一点,密码长度必须在8到20个字符之间。
我知道我必须使用{8,20}
(我认为),但问题是,无论我在哪里输入它,都会完全杀死搜索。
有人知道如何解决这个问题吗?
非常感谢。
答案 0 :(得分:1)
[免责声明,这是一个很长的答案!]
我将从字符限制开始。
您必须使用(?<!\S)
和(?!\S)
来指明密码的开头和结尾,并使用\S{8,20}
作为实际密码:
(?m)(?<!\S)\S{8,20}(?!\S)
您可能已经知道(?m)
用于多行(^
和$
分别匹配行的开头和结尾而不是此模式中的字符串。)
(?<!\S)
确保密码前没有非空白字符。
(?!\S)
确保密码后面没有非空白字符。
现在我们添加一些限制:
无法以数字或下划线开头:(?![0-9_])
在密码开头显示负面预测:
(?m)(?<!\S)(?![0-9_])\S{8,20}(?!\S)
密码开头必须至少包含一位数字:(?=\S+[0-9])
一个正向前瞻:
(?m)(?<!\S)(?![0-9_])(?=\S+[0-9])\S{8,20}(?!\S)
必须以相同的字符结尾:您必须捕获倒数第二个字符并使用反向引用。您可以将\S{8,20}
部分更改为\S{6,18}(\S)\1
:
(?m)(?<!\S)(?![0-9_])(?=\S+[0-9])\S{6,18}(\S)\1(?!\S)
现在应该是好的。
现在正在使用正则表达式:
(?m:^([^_|^0-9]{1})
首先,{1}是多余的,因为如果删除它,它根本不会改变任何内容。
(?m:^([^_|^0-9])
其次,你有不平衡的括号。不知道应该是什么,但我想第一个paren并不打算。
(?m:^[^_|^0-9])
接下来,字符类[^_|^0-9]
匹配除_
,|
,^
或范围0-9
以外的任何字符。我确定密码可以以|
或^
开头。元字符|
在字符类中失去意义!你可以使用它:[^_0-9]
代替,这将成为:
(?m:^[^_0-9])
可以使用它,但你必须记住这是密码中的第一个字符;因为你有8到20个字符的范围,它只是改为7,19。唯一剩下的就是它也接受了一个空间。您可以在字符类中放置一个以避免这种情况:
(?m:^[^_0-9 ])
好的,现在看起来更好,下一个:
(?<finalTwo>(?i:\S{1}))(?i:\<finalTwo>)
首先是一个命名的捕获组,好吧,一个非捕获组,不区分大小写模式(不是必需的,因为我们在正则表达式中没有任何字母表)和\S{1}
里面的非捕获组。再次,{1}
是多余的。删除它和(?i)
模式,这将变为:
(?<finalTwo>\S)(?:\<finalTwo>)
这不是那么糟糕,如果它与最后两个角色匹配,它确实会起作用。
(?=.*\d)
运作良好。您可能想要查找0-9
匹配的\d
以外的字符,但如果您不介意,那几乎可以使用;最好在这里使用\S
代替.
,以防万一有两个密码在文本中彼此相邻的空格分隔,这可能会使事情变得不像你想要的那样。 / p>
(\S*)
那部分或多或少没问题。没有限制。
(?=\S*\d)(?m:^[^_0-9 ])(\S*)(?<finalTwo>\S)(?:\<finalTwo>)
好的,现在,请记住(?m:^[^_0-9])
占用了一个字符,而(?<finalTwo>\S)(?:\<finalTwo>)
占用了两个字符,共计3个字符。因此,您施加的限制为:
(?=\S*\d)(?m:^[^_0-9 ])(\S{5,17})(?<finalTwo>\S)(?:\<finalTwo>)
它几乎可以工作,你只需要放一些东西来阻止长密码的部分匹配。您通常可以使用单词边界\b
,但没有提及任何关于符号的内容,因此可以更安全地假设也允许使用$@4*&AUn++
之类的密码,这就是单词边界将失败的地方。这就是我建议使用负面外观的原因。
答案 1 :(得分:0)
以下内容如何:
^(?!^[^0-9]+$)[^0-9_].{5,17}(.)\1$
^
:start-of-string。
(?!^[^0-9]+$)
:确保密码不仅仅是非数字字符的组合,确保有数字。
[^0-9_]
:确保它以不是数字或下划线的东西开头。
.{5,17}
:匹配5到17次之间的任何字符。
(.)
:匹配最后一个字符,然后在第1组中捕获它。
\1
:确保最后一个字符与之前的字符相同。
$
:字符串结束。
[^0-9_]
,(.)
和\1
占用3个字符,这为.{5,17}
留下5个字符,因此5
为最小边界,因此17作为上边界,总共最多20个字符。
我知道该演示使用PHP,但这并不重要。