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