【问题标题】:Regex.. Regex.. Regex.. What a pain. How to make the regex im after?正则表达式..正则表达式..正则表达式..真痛苦。之后如何制作正则表达式?
【发布时间】:2018-03-21 09:26:40
【问题描述】:

这是一个网站链接,用于验证和检查正则表达式是否正常工作: https://regex101.com/

这是我目前使用的正则表达式:

/(?=[\x21-\x7e]{8,20})(?=[^0-9]*[0-9])(?=[^a-z]*[a-z])(?=[^A-Z]*[A-Z]).*/g

这是我正在测试的文本:

"1abcderfggdgf sdvhbsdifsdfsdf1 Ghhuidicbdbuhbdc bhdbcdbebvuheY uuvvvyuv1G 1Guhuuuyuyuby Y%*&^$^%^(^(GVGVYUKVYTUHBKBUFygyygyg

ebfuiuberiueu23423HHII"

这就是我认为这样做的:

  1. 希望匹配索引在 33 到 126 之间且长度在 8-20 之间的任何 ascii 字符
  2. 查找在数字 0 次或更多次之前的非数字(从我读到的内容,这显然可以检测到是否存在数字)
  3. 检查在我的 0 个或多个非小写字母之前的小写字母。
  4. 用大写字母做同样的事情^^
  5. 使用 ".*" 将其作为任意字符 0 次或更多次,因为通过前瞻,它们应该缩小范围,因此不是每个字符都被允许并且它应该匹配前瞻选择的内容

这就是我想要它做的:

验证遵循这些细节的密码 -

  • 必须至少有 1 个小写字母
  • 必须至少有 1 个大写字母
  • 必须至少有 1 个号码
  • 长度只能介于 8 - 20 个字符之间
  • ascii 中的字符只能是 33 到 126,不包括空白字符 (我从哪里得到这个?-https://kb.wisc.edu/page.php?id=4073

补充说明:

我一直在正则表达式末尾使用全局 (?thing) 来指定不要在第一次匹配时停止我认为对于我的密码字段我不需要这个,因为它应该只限于 20 个字符。(我不确定)

检测一个字符是否连续使用超过 3 次也很酷,但目前没有必要。

密码输入到我的 php 文件中的表单中。 我试图将其用作输入标签的验证器。

目前还没有代码不允许使用空格。

【问题讨论】:

  • 您的正则表达式至少看起来是正确的。您的确切问题是什么?
  • 我的问题是什么是我正在寻找的正确的正则表达式以及它是如何工作的“$” 字符在代码中似乎不匹配任何东西
  • 标题中的“im”是什么意思?
  • 这是在挖苦我吗?我草率的写作方式我是或我是。
  • @guest271314 得到了你的评论我还不能投票,在阅读之后我意识到这个评论可能不被鼓励,或者仍然认为我的感谢是有效的,即使它违反了网站指南,因为你刚刚写了一个对我很有帮助的答案,就像其他人猜测的那样,当我得到足够的分数时,我可以投票以表示感谢,哈哈

标签: javascript regex html passwords


【解决方案1】:

我看到的唯一“错误”是您试图在不使用锚点的情况下限制长度 - 您允许匹配 20 个字符,但您没有检查您是否匹配了整个输入。这应该有效:

(?=^[\x21-\x7e]{8,20}$)(?=[^0-9]*[0-9])(?=[^a-z]*[a-z])(?=[^A-Z]*[A-Z]).*

工作示例(点击“运行测试”):https://regex101.com/r/L4uia8/3/tests

这是一个风格问题,但我倾向于将.* 替换为更重要的前瞻,因此(这类似于在条件中删除and true):

^(?=[^0-9]*[0-9])(?=[^a-z]*[a-z])(?=[^A-Z]*[A-Z])[\x21-\x7e]{8,20}$

工作示例:https://regex101.com/r/L4uia8/4/tests

一般来说,你shouldn't limit the length of passwords

【讨论】:

  • 锚就是他们所谓的(我不记得我的坏事),是的,我遇到了他们不工作的麻烦。上面的答案似乎几乎可以工作,除了它匹配没有大写字母的行上的字符串,也不匹配 "Y%*&^$^%^(^(GVGVYUKVYTUHBKBUFygyygyg ebfuiuberiueu23423HHII" 我看到你在上面使用了多行所以它应该匹配这些我想。
  • @Ahurasim - 我不确定你的意思。这两行与我的模式不匹配 - 我在这里提供了一个示例:regex101.com/r/L4uia8/1
  • OHH :) 我刚刚意识到最后两个不应该匹配,因为前 20 个字符没有匹配所需的内容,这是正确的吗?前两个匹配的仍然是一个问题
  • @Ahurasim - 这是因为换行。试试这个:regex101.com/r/L4uia8/3/tests
  • 为此干杯我检查了一下,它似乎可以工作,尽管你没有省略空格我接受了答案,在与朋友交谈后,有人建议我允许任何想要省略空格的人使用空格bulbus已对上述内容发表了评论
【解决方案2】:

您可以为每个人使用RegExp

  • 必须至少有 1 个小写字母
  • 必须至少有 1 个大写字母
  • 必须至少有 1 个号码
[/[a-z]/, /[A-Z]/, /[0-9]/]

创建一个包含要匹配的字符的字符串

  • ascii 中的字符只能是 33 到 126 之间的字符,不包括空格字符
[match] = Array.from({length:126 + 1 - 33})
.reduce(([key, prop]) => 
 [key += String.fromCharCode(prop), ++prop], ["", 33]))

检查字符串中的字符是否在有效字符范围内

 && [...str].every(s => match.indexOf(s) > -1)

并检查字符串的.length

&& str.length.length >= 8 
&& str.length < 21;

const check = (str
              , [match] = Array.from({length:126 + 1 - 33})
                .reduce(([key, prop]) => 
                  [key += String.fromCharCode(prop), ++prop],["", 33])
              , re = [/[a-z]/, /[A-Z]/, /[0-9]/]
              , minLength = 8
              , maxLength = 20 + 1) => 
                  re.every(regex => regex.test(str)) 
                  && [...str].every(s => match.indexOf(s) > -1)
                  && str.length >= minLength
                  && str.length < maxLength;

let [...strings] = ["aB1!!@{@@}}", "Def//3\\21", "gHI//0 \12"];

strings.forEach(str => console.log(check(str)))

【讨论】:

  • 可以用代码表达其中的一些需求是个好点,但是这里有几个问题。 /[A-Z] 丢失 /,str.length.length 未定义,字符范围检查难以辨认(each character 上的 every 更适合这里)。
  • @guest271314 只是想感谢您的回答,即使我接受了其他人的回答我认为这也是一个很好的回答:)如果我能以某种方式喜欢它,我会(不太熟悉SO的积分系统尚未)
猜你喜欢
  • 2015-12-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多