【问题标题】:What is wrong in my regex /(?=^[a-z]+\d{2,})(?=\w{5,})/ pattern?我的正则表达式 /(?=^[a-z]+\d{2,})(?=\w{5,})/ 模式有什么问题?
【发布时间】:2020-11-10 07:12:37
【问题描述】:

此正则表达式必须匹配长度超过 5 个字符、不以数字开头且具有两个连续数字的密码。

所有测试用例都通过了正则表达式测试。

我的正则表达式是/(?=^[a-z]+\d{2,})(?=\w{5,})/

我必须使用两个肯定的前瞻来解决这个问题才能通过测试。

但是 asr1on11aut 没有通过测试。为什么?

问题链接-https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/regular-expressions/positive-and-negative-lookahead

【问题讨论】:

  • 它失败了,因为“astr1on11aut”以字母开头(匹配^[a-z]+),然后有一个数字与您的约束\d{2,}不匹配。因此,(?=^[a-z]+\d{2,}) 的测试失败。

标签: javascript regex positive-lookahead


【解决方案1】:

由于第一个前瞻模式(?=^[a-z]+\d{2,}),您的正则表达式失败。字符串“astr1on11aut”以小写字母开头:

astr1on11aut
^^^^

这匹配^[a-z]+。然而,模式的下一部分需要两个或多个数字,\d{2,},然而字符串在那个地方只有一个:

   astr1on11aut
       ^^
       ||
digit -+|
        + --- not a digit

这会导致第一个前瞻模式失败。

您可以使用三个前瞻更清晰地表达验证规则:

  • "长度大于5个字符:(?=.{5,})
  • “不要以数字开头”:^(?!\d)
  • “并且有两个连续的数字”:(?=.*\d{2})

如果我们把它们放在一起,我们会得到/(?=.{5,})(?!^\d)(?=.*\d{2})/

const regex = /^(?=.{5,})(?!\d)(?=.*\d{2})/;

test("abc");
test("123");
test("123abc");

test("abc123");
test("astr1on11aut");

test("., ;_'@=-%");
test("., ;_'@123=-%");

function test(string) {
  console.log(`${string} : ${regex.test(string)}`);
}

请注意,此正则表达式不需要字母。严格按照要求,唯一明确要求的是数字。由于没有指定任何其他输入的类型,所以它可以是任何东西(使用.)。编写正则表达式时最好不要做太多假设,否则可能会阻塞合法输入。

【讨论】:

    【解决方案2】:

    如果您不限于使用 single 正则表达式,我建议将其拆分为您的宿主语言(例如 JavaScript)中的多个测试:

    if (input.match(/^\D/)
        && input.match(/\d{2}/)
        && input.length >= 5) {
      // password policy fulfilled
    }
    

    【讨论】:

    • 我所知道的所有 JS 引擎都支持 Lookaheads。旧版本不支持查看后面
    • 谢谢。让我们保持更简单的答案:并非所有事情都必须作为单个正则表达式来解决。大多数情况下,您都有一种宿主语言,所以让我们利用它的力量吧。
    • 阿门。我觉得我在正则表达式标签上的大部分时间都花在提醒人们您不需要 正则表达式来处理与字符串有关的所有事情。但是,OP 的任务与在这里制作正则表达式特别相关。我仍然支持一个不仅使用它的解决方案,因为我们真的应该更多地教人们如何使用字符串并减少对正则表达式的依赖。这是一个有用的工具,但经常被那些实际上并不理解正则表达式但仍决定使用它们的人误用和误用。电子邮件验证让我哭了。
    【解决方案3】:

    这对你有用吗?

    (?=^\D.{5,}$).*(?=\d{2,})
    

    第一个前瞻断言字符串不能以数字开头,但至少有 6 个字符长;第二个断言必须至少有 2 个连续的数字。

    【讨论】:

      【解决方案4】:

      这个正则表达式通过了所有的测试

      /(?=\w*\d\d)(?=\w{5,})(?=^[^0-9]\w*)/
      

      我相信你可以通过拆分第一组来解决你的问题。

      【讨论】:

        猜你喜欢
        • 2014-09-18
        • 1970-01-01
        • 2013-10-01
        • 1970-01-01
        • 2022-07-26
        • 1970-01-01
        • 2013-09-13
        相关资源
        最近更新 更多