代码之家  ›  专栏  ›  技术社区  ›  Kamil Kiełczewski

用于检查字符串是否包含混合字符的regexp:0-n数字和0-m字母

  •  1
  • Kamil Kiełczewski  · 技术社区  · 6 年前

    我试图找到一个正则表达式,它允许我传递具有0-n数字和0-m小写字母的字符串,其中 字母和数字可以混合 . 不允许使用任何其他字符。到目前为止,我还不知道“混合”是如何工作的

    // example n and m values and array with input strings to test
    let n=2,m=3; 
    let s=["32abc","abc32","a3b2c","3abc2","a2","abcd23","a2b3c4","aa","32","a3b_2c"];
    
    let r=s.map(x=>/[0-9]{2}[a-z]{3}/.test(x));
    
    console.log("curr:", JSON.stringify(r));
    console.log("shoud be:   [true,true,true,true,true,false,false,true,true,false]");
    2 回复  |  直到 6 年前
        1
  •  1
  •   Wiktor Stribiżew    6 年前

    可以用单个regex实现:

    let n=2,m=3; 
    let s=["32abc","abc32","a3b2c","3abc2","a2","abcd23","a2b3c4","aa","32", "a3b_2c"];
    let rx = new RegExp(
        "^" +                                         // Start of string
        "(?=(?:[^0-9]*[0-9]){0," + n + "}[^0-9]*$)" + // only 0 to n digits
        "(?=(?:[^a-z]*[a-z]){0," + m + "}[^a-z]*$)" + // only 0 to m letters
        "[a-z0-9]*" +                                 // only allow 0 or more letters/digits
        "$"                                           // End of string
    );
    let r=s.map(x=> rx.test(x));
    
    console.log("current is:", JSON.stringify(r));
    console.log("shoud be:   [true,true,true,true,true,false,false,true,true,false]");

    regex demo .

    细节

    • ^ -字符串开头
    • (?=(?:[^0-9]*[0-9]){0,2}[^0-9]*$) -一种正向前看的方法,要求在当前位置的右边立即出现零到两个除数字以外的0+字符,然后出现一个数字,然后出现除数字以外的0+字符,最后出现到字符串末尾的0+字符。
    • (?=(?:[^a-z]*[a-z]){0,3}[^a-z]*$) -一种正向前看的方法,要求在当前位置的右边立即出现0到2个除小写ASCII字母以外的任何0+字符,然后出现一个数字,然后出现0+字符(除小写ASCII字母以外的字符)到字符串的末尾。
    • [a-z0-9]* -0或更多小写ASCII字母或数字
    • $ -字符串结束
        2
  •  4
  •   CertainPerformance    6 年前

    考虑使用全局标志分别测试字母和数字,并检查全局匹配数组的长度是否为 n m 分别:

    let n = 2,
      m = 3; // example n and m values
    let s = ["32abc", "abc32", "a3b2c", "3abc2", "a2", "abcd23", "a2b3c4", "aa", "32"];
    
    
    let r = s.map(str => (
      /^[0-9a-z]*$/.test(str) &&
      (str.match(/[0-9]/g) || []).length <= n &&
      (str.match(/[a-z]/g) || []).length <= m
    ));
    console.log("current is:", JSON.stringify(r));
    console.log("shoud be:   [true,true,true,true,true,false,false,true,true]");

    或者,更复杂,但可能更优雅,而不创建空的中间数组:

    let n = 2,
      m = 3; // example n and m values
    let s = ["32abc", "abc32", "a3b2c", "3abc2", "a2", "abcd23", "a2b3c4", "aa", "32"];
    
    
    let r = s.map((str, i) => {
      const numMatch = str.match(/[0-9]/g);
      const numMatchInt = numMatch ? numMatch.length : 0;
      const alphaMatch = str.match(/[a-z]/g);
      const alphaMatchInt = alphaMatch ? alphaMatch.length : 0;
      return numMatchInt <= n && alphaMatchInt <= m && /^[0-9a-z]*$/.test(str);
    });
    console.log("current is:", JSON.stringify(r));
    console.log("shoud be:   [true,true,true,true,true,false,false,true,true]");