为了账号安全,请及时绑定邮箱和手机立即绑定

正则表达式检测具有 2+ 数字和 2+ 字符的单词

正则表达式检测具有 2+ 数字和 2+ 字符的单词

慕森王 2021-05-31 14:15:13
我需要一个正则表达式来检测长度为 8 个字符的单词,其中包含 2 个以上的数字和 2 个以上的字符(无特殊字符)。我接近解决方案,我在regex101.com上做了正则表达式。问题是包含一个数字的单词不应该与我的正则表达式相关。我丢弃了所有包含最少 7 个字符的字符的单词(?![A-Za-z]{7,})。我丢弃了所有带有包含最少 7 个数字的数字的单词(?![\d]{7,})。我丢弃了包含最少 2 个数字和 2 个字符的单词(?=[a-zA-Z\d]{2})[A-Za-z\d]{8}。为什么vaff8loe是匹配的?我创建了这个正则表达式,因为在我必须用 ******* 替换整个单词之后。喜欢:papave23 ciao il mio pin papaver1 è reeredji332ji con vaff8loe 1234567o 123t123t papavero 9o 123t123y替换后(“正则表达式”,“********”)********ciao il mio pin papaver1 è reeredji332ji con ******** 1234567o ******** papavero 9o ********
查看完整描述

3 回答

?
翻过高山走不出你

TA贡献1875条经验 获得超3个赞

使用 2 个零宽度正向前瞻:


(?=.*?[a-zA-Z].*?[a-zA-Z])    Must contain 2 ASCII letters

(?=.*?[0-9].*?[0-9])          Must contain 2 digits

[a-zA-Z0-9]{8}                Must be exactly 8 letters and/or digits

添加^和$如果不matches()用于运行正则表达式。


这意味着一个完整的正则表达式:


^(?=.*?[a-zA-Z].*?[a-zA-Z])(?=.*?[0-9].*?[0-9])[a-zA-Z0-9]{8}$

为获得最佳性能,请将.模式替换为负字符类。在这种情况下,您可能希望使用重复的非捕获组来缩短它:


(?=(?:[^a-zA-Z]*[a-zA-Z]){2})

(?=(?:[^0-9]*[0-9]){2})

更新


由于问题已更新为需要正则表达式用 * 替换此类单词,应将锚点^和$锚点更改为\b单词边界模式,并且必须将负字符类更改为仅跳过有效字符:


s = s.replaceAll("\\b(?=(?:[0-9]*[a-zA-Z]){2})(?=(?:[a-zA-Z]*[0-9]){2})[a-zA-Z0-9]{8}\\b", "********");

有关演示,请参阅regex101。


请注意,vaff8loe在给定的示例中仅包含 1 个数字,因此不应替换。


查看完整回答
反对 回复 2021-06-03
?
冉冉说

TA贡献1877条经验 获得超1个赞

您可以使用正向前瞻模式来限制数字和字母的数量:

\b(?=(?:\w*\d){2}\w*)(?=(?:\w*[A-Za-z]){2}\w*)\w{8}\b

演示:https : //regex101.com/r/z33bUv/7


查看完整回答
反对 回复 2021-06-03
?
慕姐8265434

TA贡献1813条经验 获得超2个赞

在您需要将如此多的条件应用于解析的情况下(单词必须具有长度 == 8、2+ 个字母字符、2+ 个数字字符且没有特殊字符),我认为您应该努力寻找可以阅读的解决方案而不是抛出单个复杂正则表达式中的所有内容。


假设您使用@Andreas解决方案,您的代码将如下所示:


let s = "papave23 ciao il mio pin papaver1 è reeredji332ji con vaff8loe 1234567o 123t123t papavero 9o 123t123y";


s = s.replace(/\b(?=(?:[0-9]*[a-zA-Z]){2})(?=(?:[a-zA-Z]*[0-9]){2})[a-zA-Z0-9]{8}\b/g, "********");


console.log(s);

目前还不清楚您在这里做什么,最终的错误和/或逻辑更改将难以维护。相反,您可以利用函数替换参数来分解规则。然后你会有这样的事情:


let s = "papave23 ciao il mio pin papaver1 è reeredji332ji con vaff8loe 1234567o 123t123t papavero 9o 123t123y";


// The first regex filters only 8-length words

s = s.replace(/\b\w{8}\b/g, 

    function(fullMatch) {

      // .match() can return null if no match is found, 

      // so I'm accounting for this.

      const digitMatch = fullMatch.match(/\d/g) || [];

      const letterMatch = fullMatch.match(/[a-zA-Z]/g) || [];

      const specialCharMatch = fullMatch.match(/\[^a-zA-Z0-9]/g);


      if (digitMatch.length >= 2

       && letterMatch.length >= 2

       && specialCharMatch === null) {

        return "********";

       } else {

        return fullMatch;

       }

  });


console.log(s);

它更冗长,但也更具可读性和可调试性。



查看完整回答
反对 回复 2021-06-03
  • 3 回答
  • 0 关注
  • 155 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信