验证密码的最小/最大长度。

时间:2022-04-24 11:50:19

I'm pretty new to Regex, only just started learning it in school. I got my first assignment and am getting through it fairly well.

我对Regex很陌生,刚开始在学校学习。我完成了我的第一个任务,并且过得很好。

Let me explain so my code makes sense... The assignment is making my .NET Regex Tester search through a text for passwords. These passwords can not contain any whitespaces (so I used \S) Can't start with a number or Underscore, so I used (?m:^([^_|^0-9]{1}) Can't end on two different characters

让我解释一下,这样我的代码就有意义了……作业是让我的。net Regex测试器通过文本搜索密码。这些密码不能包含任何空格(所以我用\ S)不能以数字或下划线,所以我使用(? m:^((^ _ | ^ 0 - 9]{ 1 })不能结束在两个不同的字符

(?<finalTwo>(?i:\S{1}))(?i:\<finalTwo>)

Have to contain at least one digit, so I used a lookahead. Now, the thing here is, the code is a pretty cluttered thing right now.

必须包含至少一个数字,所以我使用了前视。现在,这里的问题是,代码现在很混乱。

(?=.*\d)(?m:^([^_|^0-9]{1})(\S*)(?<finalTwo>(?i:\S{1}))(?i:\<finalTwo>))

And I have to add one more thing, the password has to be between 8 and 20 characters long. I know I have to use {8,20} (I think), but the thing is, no matter where I enter this, it completely kills the search.

我还需要添加一个东西,密码必须在8到20个字符之间。我知道我必须使用{8,20}(我想),但问题是,无论我在哪里输入这个,它都会完全杀死搜索。

Does anybody have an idea how I can solve this?

有人知道我怎么解决这个问题吗?

Much appreciated.

感谢。

2 个解决方案

#1


1  

[Disclaimer, that's a pretty long answer!]

[免责声明,这是一个相当长的回答!]

I will begin with the character limit.

我将从字符限制开始。

You'll have to use (?<!\S) and (?!\S) to indicate the beginning and end of the password and use \S{8,20} for the actual password:

您必须使用(?

(?m)(?<!\S)\S{8,20}(?!\S)

As you probably already know (?m) is for multiline (^ and $ matches beginning and end of line respectively instead of the string in this mode).

正如您可能已经知道的(?)是多行(^和$ matches分别行而不是字符串的开始和结束在这种模式下)。

(?<!\S) makes sure there's no non-whitespace character before the password.

(?

(?!\S) makes sure there's no non-whitespace character after the password.

(?!\S)确保密码后没有非空格字符。

Now we add some restrictions:

现在我们添加一些限制:

Cannot begin with number or underscore: (?![0-9_]) a negative lookahead at the start of the password:

不能以数字或下划线开头:(?![0-9_])

(?m)(?<!\S)(?![0-9_])\S{8,20}(?!\S)

Must contain at least one digit: (?=\S+[0-9]) a positive lookahead at the start of the password:

必须包含至少一个数字:(?=\S+[0-9])

(?m)(?<!\S)(?![0-9_])(?=\S+[0-9])\S{8,20}(?!\S)

Must end with the same characters: You'll have to capture the second to last character and use a backreference. You can change the \S{8,20} part to \S{6,18}(\S)\1 for this:

必须以相同的字符结束:您将不得不捕获第二个到最后一个字符并使用一个反向引用。可以将\{8,20}部分更改为\ {6,18}(\S)\1:

(?m)(?<!\S)(?![0-9_])(?=\S+[0-9])\S{6,18}(\S)\1(?!\S)

Now that should be good.

这应该很好。


To your regex now:

你现在的正则表达式:

(?m:^([^_|^0-9]{1})

First, the {1} is redundant because if you remove it, it wouldn't change anything at all.

首先,{1}是冗余的,因为如果删除它,它就不会改变任何东西。

(?m:^([^_|^0-9])

Second, you have unbalanced parentheses. Not sure what's that supposed to be, but I guess the first paren wasn't intended.

第二,括号不平衡。不知道那是什么,但我猜第一个帕伦不是故意的。

(?m:^[^_|^0-9])

Next, the character class [^_|^0-9] matches any character except _, |, ^ or the range 0-9. I'm sure that a password can begin with | or ^. The metacharacter | loses its meaning in a character class! You could use this: [^_0-9] instead and this would become:

接下来,人物类(^ _ | ^ 0 - 9]匹配任何字符除了_ | ^或范围0 - 9。我相信一个密码就可以开始|或^。元字符|在字符类中失去了它的意义!你可以使用这个:[^ _0-9)相反,这将成为:

(?m:^[^_0-9])

It's okay to use this, but you will have to keep in mind that this is the first character in the password; for you have a range of 8 to 20 characters to respect, and it just changed to 7,19. The only thing left with it is that it also accepts a space. You can put one in the character class to avoid this:

使用这个是可以的,但是您必须记住这是密码中的第一个字符;因为你有8到20个字符来表示尊敬,然后它就变成了7,19。唯一剩下的就是它也接受一个空间。你可以在角色类中加入一个来避免以下情况:

(?m:^[^_0-9 ])

Okay, looks better now, next one:

现在看起来好多了,下一个

(?<finalTwo>(?i:\S{1}))(?i:\<finalTwo>)

First is a named capture group, okay, with a non-capture group with case insensitivity mode on (not quite necessary since we don't have any alphabets in the regex) and \S{1} inside that non-capture group. Once again, the {1} is redundant. Removing it and the (?i) mode, this becomes:

首先是一个命名的捕获组,好吧,它有一个非捕获组,它的大小写不敏感模式为on(不太必要,因为在regex中没有任何字母),而在这个非捕获组中有一个\S{1}。同样,{1}是冗余的。去掉它和(?i)模式,就变成:

(?<finalTwo>\S)(?:\<finalTwo>)

That's not so bad, if it matches the last two character, it'll indeed work.

这并不是很糟糕,如果它匹配最后两个字符,它确实可以工作。

(?=.*\d)

Works well. You might want to lookout for the characters other than 0-9 that \d matches, but if you don't mind, that works almost; it'd be better to use \S instead of . here just in case there are two passwords separated by a space next to each other in the text and this might make things go not like you intended.

工作得很好。你可能想要寻找除0-9之外的与之匹配的字符,但是如果你不介意的话,这几乎是可行的;最好用\S代替。这里有两个密码在文本中被相邻的空格隔开,这可能会让事情变得不像你想的那样。

(\S*)

That part's more or less okay. There's just no limit imposed.

那部分差不多可以。没有限制。

(?=\S*\d)(?m:^[^_0-9 ])(\S*)(?<finalTwo>\S)(?:\<finalTwo>)

Okay, now, remember that (?m:^[^_0-9]) took one character, and (?<finalTwo>\S)(?:\<finalTwo>) takes two characters, for a total of 3. The limit you thus impose is:

好了,现在,记住(? m:^(^ _0-9])把一个字符,和(? < finalTwo > \ S)(?:\ < finalTwo >)需要两个字符,总共3。你因此施加的限制是:

(?=\S*\d)(?m:^[^_0-9 ])(\S{5,17})(?<finalTwo>\S)(?:\<finalTwo>)

It almost works, and you only need to put something to prevent partial match of longer passwords. You can usually use word boundaries \b but nothing has been mentioned about symbols, so it's safer to assume that a password like $@4*&AUn++ is also allowed and that's where the word boundaries will fail. That's why I suggest the use of the negative lookarounds.

它几乎可以工作,你只需要放一些东西来防止长密码的部分匹配。您通常可以使用单词边界\b,但是没有提到符号,因此更安全的假设是,$@4*&AUn++ +也允许使用密码,这就是单词边界将失败的地方。这就是为什么我建议使用消极的变通方法。

#2


0  

How about the following:

如何:

^(?!^[^0-9]+$)[^0-9_].{5,17}(.)\1$

^: start-of-string.

^:start-of-string。

(?!^[^0-9]+$): Make sure there is a digit by ensuring that the password isn't just a combination of non-digit characters.

(? ! ^ ^ 0 - 9]+ $):确保有一个数字,确保密码不只是non-digit字符的组合。

[^0-9_]: Make sure it starts with something that is not a digit or underscore.

[^ 0-9_]:确保它开始的东西不是一个数字或下划线。

.{5,17}: Match any character between 5 and 17 times.

.{5,17}:匹配5到17次之间的任何字符。

(.): Match the character just before the last one, and capture it in group 1.

(.):在最后一个字符之前匹配该字符,并将其捕获到组1中。

\1: Make sure the last character is the same as the one before it.

\1:确保最后一个字符与前一个字符相同。

$: End-of-string.

美元:字符串末尾。

[^0-9_], (.) and \1 take up 3 characters, this leaves 5 characters as minimum for .{5,17} and hence the 5 as the minimum boundary, and hence 17 as the upper boundary which makes a total maximum of 20 characters.

[^ 0-9_],(。)和\ 1占用3个字符,这使得作为最低5字符。{ 5、17 },因此5为最小边界,因此17的上边界使得总最多20个字符。

Regex101 Demo

Regex101演示

I Know the demo uses PHP, but it doesn't really matter here.

我知道演示程序使用PHP,但这并不重要。

#1


1  

[Disclaimer, that's a pretty long answer!]

[免责声明,这是一个相当长的回答!]

I will begin with the character limit.

我将从字符限制开始。

You'll have to use (?<!\S) and (?!\S) to indicate the beginning and end of the password and use \S{8,20} for the actual password:

您必须使用(?

(?m)(?<!\S)\S{8,20}(?!\S)

As you probably already know (?m) is for multiline (^ and $ matches beginning and end of line respectively instead of the string in this mode).

正如您可能已经知道的(?)是多行(^和$ matches分别行而不是字符串的开始和结束在这种模式下)。

(?<!\S) makes sure there's no non-whitespace character before the password.

(?

(?!\S) makes sure there's no non-whitespace character after the password.

(?!\S)确保密码后没有非空格字符。

Now we add some restrictions:

现在我们添加一些限制:

Cannot begin with number or underscore: (?![0-9_]) a negative lookahead at the start of the password:

不能以数字或下划线开头:(?![0-9_])

(?m)(?<!\S)(?![0-9_])\S{8,20}(?!\S)

Must contain at least one digit: (?=\S+[0-9]) a positive lookahead at the start of the password:

必须包含至少一个数字:(?=\S+[0-9])

(?m)(?<!\S)(?![0-9_])(?=\S+[0-9])\S{8,20}(?!\S)

Must end with the same characters: You'll have to capture the second to last character and use a backreference. You can change the \S{8,20} part to \S{6,18}(\S)\1 for this:

必须以相同的字符结束:您将不得不捕获第二个到最后一个字符并使用一个反向引用。可以将\{8,20}部分更改为\ {6,18}(\S)\1:

(?m)(?<!\S)(?![0-9_])(?=\S+[0-9])\S{6,18}(\S)\1(?!\S)

Now that should be good.

这应该很好。


To your regex now:

你现在的正则表达式:

(?m:^([^_|^0-9]{1})

First, the {1} is redundant because if you remove it, it wouldn't change anything at all.

首先,{1}是冗余的,因为如果删除它,它就不会改变任何东西。

(?m:^([^_|^0-9])

Second, you have unbalanced parentheses. Not sure what's that supposed to be, but I guess the first paren wasn't intended.

第二,括号不平衡。不知道那是什么,但我猜第一个帕伦不是故意的。

(?m:^[^_|^0-9])

Next, the character class [^_|^0-9] matches any character except _, |, ^ or the range 0-9. I'm sure that a password can begin with | or ^. The metacharacter | loses its meaning in a character class! You could use this: [^_0-9] instead and this would become:

接下来,人物类(^ _ | ^ 0 - 9]匹配任何字符除了_ | ^或范围0 - 9。我相信一个密码就可以开始|或^。元字符|在字符类中失去了它的意义!你可以使用这个:[^ _0-9)相反,这将成为:

(?m:^[^_0-9])

It's okay to use this, but you will have to keep in mind that this is the first character in the password; for you have a range of 8 to 20 characters to respect, and it just changed to 7,19. The only thing left with it is that it also accepts a space. You can put one in the character class to avoid this:

使用这个是可以的,但是您必须记住这是密码中的第一个字符;因为你有8到20个字符来表示尊敬,然后它就变成了7,19。唯一剩下的就是它也接受一个空间。你可以在角色类中加入一个来避免以下情况:

(?m:^[^_0-9 ])

Okay, looks better now, next one:

现在看起来好多了,下一个

(?<finalTwo>(?i:\S{1}))(?i:\<finalTwo>)

First is a named capture group, okay, with a non-capture group with case insensitivity mode on (not quite necessary since we don't have any alphabets in the regex) and \S{1} inside that non-capture group. Once again, the {1} is redundant. Removing it and the (?i) mode, this becomes:

首先是一个命名的捕获组,好吧,它有一个非捕获组,它的大小写不敏感模式为on(不太必要,因为在regex中没有任何字母),而在这个非捕获组中有一个\S{1}。同样,{1}是冗余的。去掉它和(?i)模式,就变成:

(?<finalTwo>\S)(?:\<finalTwo>)

That's not so bad, if it matches the last two character, it'll indeed work.

这并不是很糟糕,如果它匹配最后两个字符,它确实可以工作。

(?=.*\d)

Works well. You might want to lookout for the characters other than 0-9 that \d matches, but if you don't mind, that works almost; it'd be better to use \S instead of . here just in case there are two passwords separated by a space next to each other in the text and this might make things go not like you intended.

工作得很好。你可能想要寻找除0-9之外的与之匹配的字符,但是如果你不介意的话,这几乎是可行的;最好用\S代替。这里有两个密码在文本中被相邻的空格隔开,这可能会让事情变得不像你想的那样。

(\S*)

That part's more or less okay. There's just no limit imposed.

那部分差不多可以。没有限制。

(?=\S*\d)(?m:^[^_0-9 ])(\S*)(?<finalTwo>\S)(?:\<finalTwo>)

Okay, now, remember that (?m:^[^_0-9]) took one character, and (?<finalTwo>\S)(?:\<finalTwo>) takes two characters, for a total of 3. The limit you thus impose is:

好了,现在,记住(? m:^(^ _0-9])把一个字符,和(? < finalTwo > \ S)(?:\ < finalTwo >)需要两个字符,总共3。你因此施加的限制是:

(?=\S*\d)(?m:^[^_0-9 ])(\S{5,17})(?<finalTwo>\S)(?:\<finalTwo>)

It almost works, and you only need to put something to prevent partial match of longer passwords. You can usually use word boundaries \b but nothing has been mentioned about symbols, so it's safer to assume that a password like $@4*&AUn++ is also allowed and that's where the word boundaries will fail. That's why I suggest the use of the negative lookarounds.

它几乎可以工作,你只需要放一些东西来防止长密码的部分匹配。您通常可以使用单词边界\b,但是没有提到符号,因此更安全的假设是,$@4*&AUn++ +也允许使用密码,这就是单词边界将失败的地方。这就是为什么我建议使用消极的变通方法。

#2


0  

How about the following:

如何:

^(?!^[^0-9]+$)[^0-9_].{5,17}(.)\1$

^: start-of-string.

^:start-of-string。

(?!^[^0-9]+$): Make sure there is a digit by ensuring that the password isn't just a combination of non-digit characters.

(? ! ^ ^ 0 - 9]+ $):确保有一个数字,确保密码不只是non-digit字符的组合。

[^0-9_]: Make sure it starts with something that is not a digit or underscore.

[^ 0-9_]:确保它开始的东西不是一个数字或下划线。

.{5,17}: Match any character between 5 and 17 times.

.{5,17}:匹配5到17次之间的任何字符。

(.): Match the character just before the last one, and capture it in group 1.

(.):在最后一个字符之前匹配该字符,并将其捕获到组1中。

\1: Make sure the last character is the same as the one before it.

\1:确保最后一个字符与前一个字符相同。

$: End-of-string.

美元:字符串末尾。

[^0-9_], (.) and \1 take up 3 characters, this leaves 5 characters as minimum for .{5,17} and hence the 5 as the minimum boundary, and hence 17 as the upper boundary which makes a total maximum of 20 characters.

[^ 0-9_],(。)和\ 1占用3个字符,这使得作为最低5字符。{ 5、17 },因此5为最小边界,因此17的上边界使得总最多20个字符。

Regex101 Demo

Regex101演示

I Know the demo uses PHP, but it doesn't really matter here.

我知道演示程序使用PHP,但这并不重要。