可以使用正则表达式重写此函数吗?

Tho*_*ore 10 javascript regex reformatting

我想重新格式化并验证用户是否提供了有效的比利时企业编号。由于输入可以是以下所有示例:

  • 是0123.321.123
  • BE0123.321.123
  • BE0123 321 123
  • 0123.321.123
  • 123.321.123
  • 123321123

我编写了一个函数,用于验证输入并将其重新格式化为“显示”版本(BE 0123.123.123)和“代码”版本(123123123)。此功能如下所示。

formatAndValidateEnterpriseNumber = enterpriseNumber => {
    if(enterpriseNumber === undefined || !enterpriseNumber || (enterpriseNumber || '').length < 3) return { isValid: false, error: 'Please fill in your enterprise number' };

        //Remove space, dots, ...
        enterpriseNumber = enterpriseNumber.toUpperCase();
        enterpriseNumber = enterpriseNumber.replace(/[. ,:-]+/g, '');

        //Check for double country code
        const reDouble = /^[a-zA-Z]{4}/;
        if (reDouble.test(enterpriseNumber)) enterpriseNumber = enterpriseNumber.substring(2);

        if (enterpriseNumber.length < 9 || enterpriseNumber.length > 12) return { isValid: false, error: 'The length of the provided number is incorrect' };

        //Check country code
        const reBE = /^[a-zA-Z]{2}/;
        if (reBE.test(enterpriseNumber)) {
            //Check if country code = BE
            if (enterpriseNumber.slice(0, 2) !== 'BE') return { isValid: false, error: 'Please fill in a Belgian enterprise number' };
            // Remove country code
            else enterpriseNumber = enterpriseNumber.substring(2);
        }

        //Check if first digit is 0
        if (enterpriseNumber.length === 10 && enterpriseNumber.startsWith('0')) enterpriseNumber = enterpriseNumber.substring(1);

        //Check if enterpriseNumber is valid with modulo test
        if (parseInt(97 - (enterpriseNumber.slice(0, 7) % 97), 10) !== parseInt(enterpriseNumber.slice(7, 9), 10))
            return { isValid: false, error: 'The provided number is invalid'}

      return {
            isValid: true,
            enterpriseNumber: enterpriseNumber,
            displayEnterpriseNumber: `BE 0${enterpriseNumber.substring(0, 3)}.${enterpriseNumber.substring(3, 6)}.${enterpriseNumber.substring(6, 9)}`
      };
};
Run Code Online (Sandbox Code Playgroud)

我认为这很混乱,我想知道是否可以通过重新格式化并验证用户输入的一两个正则表达式测试来改善这一点?

第二个问题:有时对于帐户或信用卡号,输入字段的输入框中已经有下划线和行(-),并在键入时重新设置数字的格式。这种方法叫什么,可以针对比利时企业编号之类的特定事物执行此方法吗?

Mou*_*ser 8

是的你可以:

^(?:BE)?\s*[0-1]?(\d[. ]*){9}$
Run Code Online (Sandbox Code Playgroud)

这个正则表达式应该做到这一点!

来源(荷兰语)说明比利时的企业编号是什么:

它具有国家/地区代码:BE后面跟一个01,再跟一个9位数字。

https://regex101.com/r/4SRHxi/4

说明:

  • ^:字符串必须以给定的正则表达式开头
  • (?:BE)?:寻找具有BE的群组,但?表示它匹配零或一遍- ?:表示找到但不捕获
  • \s*:搜索匹配零个或无限次的空间
  • [0-1]?:检查零的存在是零还是一
  • ((\d[. ]*){9}):检查剩余的字符串后面是否有9位数字,与填充多少点或空格无关。每次迭代均被捕获为第一个捕获组。当我们以后更换时,这变得很重要。
  • $:字符串必须结束

这将检查输入是否有效。

将其编辑为code版本很简单:

«code».replace(/^(?:BE)?\s*[0-1]?((\d[. ]*){9})$/g, function(){
      return arguments[1].replace(/\D/g, "");
});
Run Code Online (Sandbox Code Playgroud)

g 或全球性的修改将确保所有不需要的字符将被删除。通过使用带有替换功能来替换所有非数字字符。此功能将输出我们想要的结果。

^(?:BE)?\s*[0-1]?(\d[. ]*){9}$
Run Code Online (Sandbox Code Playgroud)
«code».replace(/^(?:BE)?\s*[0-1]?((\d[. ]*){9})$/g, function(){
      return arguments[1].replace(/\D/g, "");
});
Run Code Online (Sandbox Code Playgroud)

现在很容易将String重建为正确的用户友好方式:

document.querySelector("pre").textContent.split("\n").forEach(function(element){
  if (element.match(/^(?:BE)?\s*[0-1]?(\d[. ]*){9}$/))
  {
     console.log(element.replace(/^(?:BE)?\s*[0-1]?((\d[. ]*){9})$/g, function(){
      return arguments[1].replace(/\D/g, "");
     }));
  }
  else
  {
    console.log(`REJECTED: ${element}`);
  }

});
Run Code Online (Sandbox Code Playgroud)
<pre>
BE 0123.321.123
BE0123.321.123
BE0123 321 123
BE 0123  321  123
BE 01 23 32 11 23
BE 0123 32 11 23
1123.321.123
123.321.123
123321123
AAA3434343A
BE  1233 445 4545 442
</pre>
Run Code Online (Sandbox Code Playgroud)


第二个问题 是,可以这样做,但是需要您编写自己的代码。

简单版本:

document.querySelector("pre").textContent.split("\n").forEach(function(element) {
  if (element.match(/^(?:BE)?\s*[0-1]?((\d[. ]*){9})$/)) {
    var stripped = element.replace(/^(?:BE)?\s*[0-1]?((\d[. ]*){9})$/g, function(){
          return arguments[1].replace(/\D/g, "");
    });

    //with the modulo check from your code added back in.
    if (97 - (parseInt(stripped.slice(0, 7), 10) % 97) == parseInt(stripped.slice(7, 9), 10)) {
      //use a literal string
      //use substring to put the dots between the sections of three numbers.
      var humanReadable = `BE 0${stripped.substring(0,3)}.${stripped.substring(3,6)}.${stripped.substring(6,9)}`;
      console.log(`CODE: ${stripped}`, `UI: ${humanReadable}`);
    }
  }

});
Run Code Online (Sandbox Code Playgroud)
<pre>
BE 0123.321.123
BE0123.321.123
BE0123 321 123
0123.321.123
123.321.123
123321123
844256524
</pre>
Run Code Online (Sandbox Code Playgroud)
document.querySelector("div.enterprisenumber > input").addEventListener("keydown", function(e) {
  let value = this.value;

  //prevent the input from going back to 0
  if ( (value.length == 0 && (e.key == "Backspace" || e.key == "Delete"))) {
    e.preventDefault();
    return false;
  }
}, true);

document.querySelector("div.enterprisenumber > input").addEventListener("keyup", function(e) {
  //reset to a value without dots 
  let value = this.value.replace(/\./g, "");

  //strip the leading zero
  const valueWithout = value;
  //calculate how much iterations we need of a groups of three digits.
  const i = Math.floor(valueWithout.length / 3);
  let newValue = "";
  //check if backspace or delete are used to make sure the dot can be deleted.
  if (valueWithout.length < 9 && !(e.key == "Backspace" || e.key == "Delete")) {
    //only fire when higher than zero
    if (i > 0) {
      let t;
      //t is the index
      for (t = 0; t < i; t++) {
      //slice the correct portion of the string and append a dot, unless we are at the end of the groups
        newValue += valueWithout.slice(t * 3, t * 3 + 3) + (t == 2  ? "" : ".");
      }
      //append the remainder that is not a group of three.
      newValue += valueWithout.slice((t) * 3);
    } else {
      //return the value as is.
      newValue = value;
    }
    //set the new value to the input.
    this.value = newValue;
  }
}, true);

document.querySelector("div.enterprisenumber > input").addEventListener("blur", function(e) {
  let passed = false;
  if (this.value.match(/^(?:BE)?\s*[0-1]?((\d[. ]*){9})$/))
  {
    const value = this.value.replace(/\./g, "");
    //with modulo check
    if (97 - (parseInt(value.slice(0,7), 10) % 97) == value.slice(7, 9))
    {
      passed = true;
    }
  }
  document.querySelector(".enterprisenumber").classList[(passed ? "remove" : "add")]("error");
});

//if focus then focus input
document.querySelector("div.enterprisenumber").addEventListener("click", function(e) {
 if (e.target && e.target.nodeName != "SELECT")
 {
  this.querySelector("input").focus();
 }
});
Run Code Online (Sandbox Code Playgroud)

  • 请参阅我的答案中发布的解决方案。模数检查应单独进行。 (2认同)