Can this function be rewritten with a regex?

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP












9















I want to reformat and validate if a user has provided a valid Belgian enterprise number. Because the input can be all of the following examples:



  • BE 0123.321.123

  • BE0123.321.123

  • BE0123 321 123

  • 0123.321.123

  • 123.321.123

  • 123321123

I've written a function that validates and reformat the input to a 'display' version (BE 0123.123.123) and a 'code' version (123123123). This function looks like this.



formatAndValidateEnterpriseNumber = enterpriseNumber => ;


I think it's pretty messy and I'm wondering if this can be improved with one/two regex tests that reformat and validate the user's input?



A second question: Sometimes for account or credit cards numbers the input field had those underscores and lines (-) already in the input box and reformat the number while typing. What is this method called and can this be done for a specific thing like a Belgian enterprise number?










share|improve this question

















  • 3





    The modulo test is not easily possible in regex.

    – trincot
    Mar 4 at 20:22















9















I want to reformat and validate if a user has provided a valid Belgian enterprise number. Because the input can be all of the following examples:



  • BE 0123.321.123

  • BE0123.321.123

  • BE0123 321 123

  • 0123.321.123

  • 123.321.123

  • 123321123

I've written a function that validates and reformat the input to a 'display' version (BE 0123.123.123) and a 'code' version (123123123). This function looks like this.



formatAndValidateEnterpriseNumber = enterpriseNumber => ;


I think it's pretty messy and I'm wondering if this can be improved with one/two regex tests that reformat and validate the user's input?



A second question: Sometimes for account or credit cards numbers the input field had those underscores and lines (-) already in the input box and reformat the number while typing. What is this method called and can this be done for a specific thing like a Belgian enterprise number?










share|improve this question

















  • 3





    The modulo test is not easily possible in regex.

    – trincot
    Mar 4 at 20:22













9












9








9


1






I want to reformat and validate if a user has provided a valid Belgian enterprise number. Because the input can be all of the following examples:



  • BE 0123.321.123

  • BE0123.321.123

  • BE0123 321 123

  • 0123.321.123

  • 123.321.123

  • 123321123

I've written a function that validates and reformat the input to a 'display' version (BE 0123.123.123) and a 'code' version (123123123). This function looks like this.



formatAndValidateEnterpriseNumber = enterpriseNumber => ;


I think it's pretty messy and I'm wondering if this can be improved with one/two regex tests that reformat and validate the user's input?



A second question: Sometimes for account or credit cards numbers the input field had those underscores and lines (-) already in the input box and reformat the number while typing. What is this method called and can this be done for a specific thing like a Belgian enterprise number?










share|improve this question














I want to reformat and validate if a user has provided a valid Belgian enterprise number. Because the input can be all of the following examples:



  • BE 0123.321.123

  • BE0123.321.123

  • BE0123 321 123

  • 0123.321.123

  • 123.321.123

  • 123321123

I've written a function that validates and reformat the input to a 'display' version (BE 0123.123.123) and a 'code' version (123123123). This function looks like this.



formatAndValidateEnterpriseNumber = enterpriseNumber => ;


I think it's pretty messy and I'm wondering if this can be improved with one/two regex tests that reformat and validate the user's input?



A second question: Sometimes for account or credit cards numbers the input field had those underscores and lines (-) already in the input box and reformat the number while typing. What is this method called and can this be done for a specific thing like a Belgian enterprise number?







javascript regex reformatting






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Mar 4 at 19:52









ThoreThore

514214




514214







  • 3





    The modulo test is not easily possible in regex.

    – trincot
    Mar 4 at 20:22












  • 3





    The modulo test is not easily possible in regex.

    – trincot
    Mar 4 at 20:22







3




3





The modulo test is not easily possible in regex.

– trincot
Mar 4 at 20:22





The modulo test is not easily possible in regex.

– trincot
Mar 4 at 20:22












3 Answers
3






active

oldest

votes


















8














Yes you can:



^(?:BE)?s*[0-1]?(d[. ]*)9$


This regex should do it!




This source (in Dutch) states what an enterprise number is for Belgium:



It has the country code: BE followed by a 0 or 1 and then followed by 9 digits.




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



Explanation:




  • ^: the string has to start with the given regex


  • (?:BE)?: look for a group with BE but ? means it matches zero or
    one times - ?: means find but don't capture


  • s*: search for a space that matches zero or unlimited times


  • [0-1]?: check if a zero of one is present zero or one times


  • ((d[. ]*)9): Check if 9 digits follow the remaining string, doesn't matter with how many dots or spaces they're padded. Every iteration is captured as the 1st capturing group. This becomes important when we replace later.


  • $: the string has to end

This will check if the input validates.



Editing it into the code version is simple:



«code».replace(/^(?:BE)?s*[0-1]?((d[. ]*)9)$/g, function()
return arguments[1].replace(/D/g, "");
);


the g or global modifier will ensure all unwanted characters will be deleted. By using a function with a replace in it to replace all non-digit characters. This functions will output our desired result.






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`);


);

<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>





Rebuilding the String into the correct user friendly way is easy now:






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`);



);

<pre>
BE 0123.321.123
BE0123.321.123
BE0123 321 123
0123.321.123
123.321.123
123321123
844256524
</pre>






Second Question
Yes, this can be done however it requires you to write your own code for it.



Simple version:






document.querySelector("div.enterprisenumber > input").addEventListener("keydown", function(e) , true);

document.querySelector("div.enterprisenumber > input").addEventListener("keyup", function(e) , 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();

);

* 
box-sizing: border-box;
font-family: tahoma;
font-size: 10pt;


div.enterprisenumber
border: 1px solid #747474;
width: 300px;
padding: 0px;
display: grid;
grid-template-columns: 25px 40px auto;
border-radius: 10px;


div.enterprisenumber.error
border: 1px solid #ff0000;


div.enterprisenumber>span
grid-column: 1;
border: 0px;
padding: 5px;
background: linear-gradient(to right, rgba(0,0,0, 0.8) 33%, rgba(255,243,54, 0.8) 33%, rgba(255, 243, 54, 0.8) 66%, rgba(255, 15, 33, 0.8) 66%, rgba(255, 15, 33, 0.8) 100%);
color: #ffffff;
font-weight: bold;
text-shadow: 1px 1px #000000;
border-radius: 10px 10px 10px 10px;


div.enterprisenumber>select
grid-column: 2;
border: 0px;
padding: 5px;


div.enterprisenumber>input
grid-column: 3;
border: 0px;
padding: 5px;
border-radius: 0px 10px 10px 0px;

Enter: 844256524
<div class="enterprisenumber">
<span>BE</span><select><option value="0">0</option><option value="1">1</option><input value="" maxlength="11" />
</div>








share|improve this answer

























  • Wow! Thanks for the explanation. I like the solution. However the modulo test is gone to check if the number is valid (The first 7 digits without the 0 or 1 in front, %97 should be the last two digits).

    – Thore
    Mar 4 at 21:44











  • that's not that difficult, but not doable in the regexp though.

    – Mouser
    Mar 4 at 22:33






  • 2





    See the solutions posted in my answer. Modulo check should be done separately.

    – Mouser
    Mar 4 at 23:10







  • 1





    Reworked the entire rexexp. Should hopefully meet your expectations. Mouser out.

    – Mouser
    Mar 5 at 0:51






  • 1





    s*? really should just be s*. The extra laziness gains us nothing, and just causes more backtracking on valid inputs.

    – amalloy
    Mar 5 at 1:01


















2














For your example strings, you could match:



^(?:BEs?)?[01]?(d3([. ])d32d3|d9)$


That will match




  • ^ Start of string


  • (?:BEs?)? Optional BE followed by optional whitespace char


  • [01]? Optional zero or 1


  • ( Capturing group


    • d3 Match 3 digits


    • ([. ]) Capture in group either a space or digit to use as backreference


    • d32d3 Match 3 digits, dot or space (2 is the backreference) and 3 digits


    • | Or


    • d9 Match 9 digits



  • ) Close capturing group


  • $ End of string

Regex demo



And then in the replacement use the first capturing group and replace the space or the dot with an empty string.






let pattern = /^(?:BEs?)?[01]?(d3([. ])d32d3|d9)$/;
let strings = [
"BE 0123.321.123",
"BE0123.321.123",
"BE0123 321 123",
"0123.321.123",
"123.321.123",
"123321123",
];

strings = strings.map(x => x.replace(pattern, function(m, g)
let enterpriseNumber = g.replace(/[. ]/g, "");
return `BE 0$enterpriseNumber.substring(0, 3).$enterpriseNumber.substring(3, 6).$enterpriseNumber.substring(6, 9)`
));

console.log(strings);








share|improve this answer
































    2














    Here is an implementation of a BE ____.___.___ style of input. The pattern will be maintained, so the input will be guaranteed to have the "BE" prefix, the space, and the two dots. The validation can then concentrate on completeness and the modulo test.



    Note that the input requires the first group to have 4 digits, where the first digit must be a 0 or a 1.






    const ent = document.getElementById("ent");
    const out = document.getElementById("isvalid");

    function format() D+/g;
    const [i, j] = [this.selectionStart, this.selectionEnd].map(i =>
    i = this.value.slice(0, i).replace(re, "").length;
    return i + 3 + (i >= 4 + format.backspace) + (i >= 7 + format.backspace);
    );
    this.value = "BE " + this.value.replace(re, "").padEnd(10, "_")
    .replace(/(....)(...)(...).*/, "$1.$2.$3");
    this.setSelectionRange(i, j);
    format.backspace = false;
    out.textContent = validate(this.value) ? "is valid" : "is invalid";


    function validate(num)
    return /^BE [01](d3.)2d3$/.test(num)
    && 97 - num.replace(/D/g, "").slice(0, 8) % 97 === +num.slice(-2);


    ent.addEventListener("input", format);
    ent.addEventListener("keydown", (e) => format.backspace = e.key == "Backspace");

    Belgian enterprise number: <input id="ent" value="BE ____.___.___">
    <span id="isvalid"></span>








    share|improve this answer























    • Wow, that's a nice solution to the second question.

      – Mouser
      Mar 4 at 23:11











    Your Answer






    StackExchange.ifUsing("editor", function ()
    StackExchange.using("externalEditor", function ()
    StackExchange.using("snippets", function ()
    StackExchange.snippets.init();
    );
    );
    , "code-snippets");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "1"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader:
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    ,
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );













    draft saved

    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54990565%2fcan-this-function-be-rewritten-with-a-regex%23new-answer', 'question_page');

    );

    Post as a guest















    Required, but never shown

























    3 Answers
    3






    active

    oldest

    votes








    3 Answers
    3






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    8














    Yes you can:



    ^(?:BE)?s*[0-1]?(d[. ]*)9$


    This regex should do it!




    This source (in Dutch) states what an enterprise number is for Belgium:



    It has the country code: BE followed by a 0 or 1 and then followed by 9 digits.




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



    Explanation:




    • ^: the string has to start with the given regex


    • (?:BE)?: look for a group with BE but ? means it matches zero or
      one times - ?: means find but don't capture


    • s*: search for a space that matches zero or unlimited times


    • [0-1]?: check if a zero of one is present zero or one times


    • ((d[. ]*)9): Check if 9 digits follow the remaining string, doesn't matter with how many dots or spaces they're padded. Every iteration is captured as the 1st capturing group. This becomes important when we replace later.


    • $: the string has to end

    This will check if the input validates.



    Editing it into the code version is simple:



    «code».replace(/^(?:BE)?s*[0-1]?((d[. ]*)9)$/g, function()
    return arguments[1].replace(/D/g, "");
    );


    the g or global modifier will ensure all unwanted characters will be deleted. By using a function with a replace in it to replace all non-digit characters. This functions will output our desired result.






    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`);


    );

    <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>





    Rebuilding the String into the correct user friendly way is easy now:






    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`);



    );

    <pre>
    BE 0123.321.123
    BE0123.321.123
    BE0123 321 123
    0123.321.123
    123.321.123
    123321123
    844256524
    </pre>






    Second Question
    Yes, this can be done however it requires you to write your own code for it.



    Simple version:






    document.querySelector("div.enterprisenumber > input").addEventListener("keydown", function(e) , true);

    document.querySelector("div.enterprisenumber > input").addEventListener("keyup", function(e) , 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();

    );

    * 
    box-sizing: border-box;
    font-family: tahoma;
    font-size: 10pt;


    div.enterprisenumber
    border: 1px solid #747474;
    width: 300px;
    padding: 0px;
    display: grid;
    grid-template-columns: 25px 40px auto;
    border-radius: 10px;


    div.enterprisenumber.error
    border: 1px solid #ff0000;


    div.enterprisenumber>span
    grid-column: 1;
    border: 0px;
    padding: 5px;
    background: linear-gradient(to right, rgba(0,0,0, 0.8) 33%, rgba(255,243,54, 0.8) 33%, rgba(255, 243, 54, 0.8) 66%, rgba(255, 15, 33, 0.8) 66%, rgba(255, 15, 33, 0.8) 100%);
    color: #ffffff;
    font-weight: bold;
    text-shadow: 1px 1px #000000;
    border-radius: 10px 10px 10px 10px;


    div.enterprisenumber>select
    grid-column: 2;
    border: 0px;
    padding: 5px;


    div.enterprisenumber>input
    grid-column: 3;
    border: 0px;
    padding: 5px;
    border-radius: 0px 10px 10px 0px;

    Enter: 844256524
    <div class="enterprisenumber">
    <span>BE</span><select><option value="0">0</option><option value="1">1</option><input value="" maxlength="11" />
    </div>








    share|improve this answer

























    • Wow! Thanks for the explanation. I like the solution. However the modulo test is gone to check if the number is valid (The first 7 digits without the 0 or 1 in front, %97 should be the last two digits).

      – Thore
      Mar 4 at 21:44











    • that's not that difficult, but not doable in the regexp though.

      – Mouser
      Mar 4 at 22:33






    • 2





      See the solutions posted in my answer. Modulo check should be done separately.

      – Mouser
      Mar 4 at 23:10







    • 1





      Reworked the entire rexexp. Should hopefully meet your expectations. Mouser out.

      – Mouser
      Mar 5 at 0:51






    • 1





      s*? really should just be s*. The extra laziness gains us nothing, and just causes more backtracking on valid inputs.

      – amalloy
      Mar 5 at 1:01















    8














    Yes you can:



    ^(?:BE)?s*[0-1]?(d[. ]*)9$


    This regex should do it!




    This source (in Dutch) states what an enterprise number is for Belgium:



    It has the country code: BE followed by a 0 or 1 and then followed by 9 digits.




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



    Explanation:




    • ^: the string has to start with the given regex


    • (?:BE)?: look for a group with BE but ? means it matches zero or
      one times - ?: means find but don't capture


    • s*: search for a space that matches zero or unlimited times


    • [0-1]?: check if a zero of one is present zero or one times


    • ((d[. ]*)9): Check if 9 digits follow the remaining string, doesn't matter with how many dots or spaces they're padded. Every iteration is captured as the 1st capturing group. This becomes important when we replace later.


    • $: the string has to end

    This will check if the input validates.



    Editing it into the code version is simple:



    «code».replace(/^(?:BE)?s*[0-1]?((d[. ]*)9)$/g, function()
    return arguments[1].replace(/D/g, "");
    );


    the g or global modifier will ensure all unwanted characters will be deleted. By using a function with a replace in it to replace all non-digit characters. This functions will output our desired result.






    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`);


    );

    <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>





    Rebuilding the String into the correct user friendly way is easy now:






    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`);



    );

    <pre>
    BE 0123.321.123
    BE0123.321.123
    BE0123 321 123
    0123.321.123
    123.321.123
    123321123
    844256524
    </pre>






    Second Question
    Yes, this can be done however it requires you to write your own code for it.



    Simple version:






    document.querySelector("div.enterprisenumber > input").addEventListener("keydown", function(e) , true);

    document.querySelector("div.enterprisenumber > input").addEventListener("keyup", function(e) , 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();

    );

    * 
    box-sizing: border-box;
    font-family: tahoma;
    font-size: 10pt;


    div.enterprisenumber
    border: 1px solid #747474;
    width: 300px;
    padding: 0px;
    display: grid;
    grid-template-columns: 25px 40px auto;
    border-radius: 10px;


    div.enterprisenumber.error
    border: 1px solid #ff0000;


    div.enterprisenumber>span
    grid-column: 1;
    border: 0px;
    padding: 5px;
    background: linear-gradient(to right, rgba(0,0,0, 0.8) 33%, rgba(255,243,54, 0.8) 33%, rgba(255, 243, 54, 0.8) 66%, rgba(255, 15, 33, 0.8) 66%, rgba(255, 15, 33, 0.8) 100%);
    color: #ffffff;
    font-weight: bold;
    text-shadow: 1px 1px #000000;
    border-radius: 10px 10px 10px 10px;


    div.enterprisenumber>select
    grid-column: 2;
    border: 0px;
    padding: 5px;


    div.enterprisenumber>input
    grid-column: 3;
    border: 0px;
    padding: 5px;
    border-radius: 0px 10px 10px 0px;

    Enter: 844256524
    <div class="enterprisenumber">
    <span>BE</span><select><option value="0">0</option><option value="1">1</option><input value="" maxlength="11" />
    </div>








    share|improve this answer

























    • Wow! Thanks for the explanation. I like the solution. However the modulo test is gone to check if the number is valid (The first 7 digits without the 0 or 1 in front, %97 should be the last two digits).

      – Thore
      Mar 4 at 21:44











    • that's not that difficult, but not doable in the regexp though.

      – Mouser
      Mar 4 at 22:33






    • 2





      See the solutions posted in my answer. Modulo check should be done separately.

      – Mouser
      Mar 4 at 23:10







    • 1





      Reworked the entire rexexp. Should hopefully meet your expectations. Mouser out.

      – Mouser
      Mar 5 at 0:51






    • 1





      s*? really should just be s*. The extra laziness gains us nothing, and just causes more backtracking on valid inputs.

      – amalloy
      Mar 5 at 1:01













    8












    8








    8







    Yes you can:



    ^(?:BE)?s*[0-1]?(d[. ]*)9$


    This regex should do it!




    This source (in Dutch) states what an enterprise number is for Belgium:



    It has the country code: BE followed by a 0 or 1 and then followed by 9 digits.




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



    Explanation:




    • ^: the string has to start with the given regex


    • (?:BE)?: look for a group with BE but ? means it matches zero or
      one times - ?: means find but don't capture


    • s*: search for a space that matches zero or unlimited times


    • [0-1]?: check if a zero of one is present zero or one times


    • ((d[. ]*)9): Check if 9 digits follow the remaining string, doesn't matter with how many dots or spaces they're padded. Every iteration is captured as the 1st capturing group. This becomes important when we replace later.


    • $: the string has to end

    This will check if the input validates.



    Editing it into the code version is simple:



    «code».replace(/^(?:BE)?s*[0-1]?((d[. ]*)9)$/g, function()
    return arguments[1].replace(/D/g, "");
    );


    the g or global modifier will ensure all unwanted characters will be deleted. By using a function with a replace in it to replace all non-digit characters. This functions will output our desired result.






    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`);


    );

    <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>





    Rebuilding the String into the correct user friendly way is easy now:






    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`);



    );

    <pre>
    BE 0123.321.123
    BE0123.321.123
    BE0123 321 123
    0123.321.123
    123.321.123
    123321123
    844256524
    </pre>






    Second Question
    Yes, this can be done however it requires you to write your own code for it.



    Simple version:






    document.querySelector("div.enterprisenumber > input").addEventListener("keydown", function(e) , true);

    document.querySelector("div.enterprisenumber > input").addEventListener("keyup", function(e) , 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();

    );

    * 
    box-sizing: border-box;
    font-family: tahoma;
    font-size: 10pt;


    div.enterprisenumber
    border: 1px solid #747474;
    width: 300px;
    padding: 0px;
    display: grid;
    grid-template-columns: 25px 40px auto;
    border-radius: 10px;


    div.enterprisenumber.error
    border: 1px solid #ff0000;


    div.enterprisenumber>span
    grid-column: 1;
    border: 0px;
    padding: 5px;
    background: linear-gradient(to right, rgba(0,0,0, 0.8) 33%, rgba(255,243,54, 0.8) 33%, rgba(255, 243, 54, 0.8) 66%, rgba(255, 15, 33, 0.8) 66%, rgba(255, 15, 33, 0.8) 100%);
    color: #ffffff;
    font-weight: bold;
    text-shadow: 1px 1px #000000;
    border-radius: 10px 10px 10px 10px;


    div.enterprisenumber>select
    grid-column: 2;
    border: 0px;
    padding: 5px;


    div.enterprisenumber>input
    grid-column: 3;
    border: 0px;
    padding: 5px;
    border-radius: 0px 10px 10px 0px;

    Enter: 844256524
    <div class="enterprisenumber">
    <span>BE</span><select><option value="0">0</option><option value="1">1</option><input value="" maxlength="11" />
    </div>








    share|improve this answer















    Yes you can:



    ^(?:BE)?s*[0-1]?(d[. ]*)9$


    This regex should do it!




    This source (in Dutch) states what an enterprise number is for Belgium:



    It has the country code: BE followed by a 0 or 1 and then followed by 9 digits.




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



    Explanation:




    • ^: the string has to start with the given regex


    • (?:BE)?: look for a group with BE but ? means it matches zero or
      one times - ?: means find but don't capture


    • s*: search for a space that matches zero or unlimited times


    • [0-1]?: check if a zero of one is present zero or one times


    • ((d[. ]*)9): Check if 9 digits follow the remaining string, doesn't matter with how many dots or spaces they're padded. Every iteration is captured as the 1st capturing group. This becomes important when we replace later.


    • $: the string has to end

    This will check if the input validates.



    Editing it into the code version is simple:



    «code».replace(/^(?:BE)?s*[0-1]?((d[. ]*)9)$/g, function()
    return arguments[1].replace(/D/g, "");
    );


    the g or global modifier will ensure all unwanted characters will be deleted. By using a function with a replace in it to replace all non-digit characters. This functions will output our desired result.






    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`);


    );

    <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>





    Rebuilding the String into the correct user friendly way is easy now:






    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`);



    );

    <pre>
    BE 0123.321.123
    BE0123.321.123
    BE0123 321 123
    0123.321.123
    123.321.123
    123321123
    844256524
    </pre>






    Second Question
    Yes, this can be done however it requires you to write your own code for it.



    Simple version:






    document.querySelector("div.enterprisenumber > input").addEventListener("keydown", function(e) , true);

    document.querySelector("div.enterprisenumber > input").addEventListener("keyup", function(e) , 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();

    );

    * 
    box-sizing: border-box;
    font-family: tahoma;
    font-size: 10pt;


    div.enterprisenumber
    border: 1px solid #747474;
    width: 300px;
    padding: 0px;
    display: grid;
    grid-template-columns: 25px 40px auto;
    border-radius: 10px;


    div.enterprisenumber.error
    border: 1px solid #ff0000;


    div.enterprisenumber>span
    grid-column: 1;
    border: 0px;
    padding: 5px;
    background: linear-gradient(to right, rgba(0,0,0, 0.8) 33%, rgba(255,243,54, 0.8) 33%, rgba(255, 243, 54, 0.8) 66%, rgba(255, 15, 33, 0.8) 66%, rgba(255, 15, 33, 0.8) 100%);
    color: #ffffff;
    font-weight: bold;
    text-shadow: 1px 1px #000000;
    border-radius: 10px 10px 10px 10px;


    div.enterprisenumber>select
    grid-column: 2;
    border: 0px;
    padding: 5px;


    div.enterprisenumber>input
    grid-column: 3;
    border: 0px;
    padding: 5px;
    border-radius: 0px 10px 10px 0px;

    Enter: 844256524
    <div class="enterprisenumber">
    <span>BE</span><select><option value="0">0</option><option value="1">1</option><input value="" maxlength="11" />
    </div>








    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`);


    );

    <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>





    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`);


    );

    <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>





    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`);



    );

    <pre>
    BE 0123.321.123
    BE0123.321.123
    BE0123 321 123
    0123.321.123
    123.321.123
    123321123
    844256524
    </pre>





    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`);



    );

    <pre>
    BE 0123.321.123
    BE0123.321.123
    BE0123 321 123
    0123.321.123
    123.321.123
    123321123
    844256524
    </pre>





    document.querySelector("div.enterprisenumber > input").addEventListener("keydown", function(e) , true);

    document.querySelector("div.enterprisenumber > input").addEventListener("keyup", function(e) , 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();

    );

    * 
    box-sizing: border-box;
    font-family: tahoma;
    font-size: 10pt;


    div.enterprisenumber
    border: 1px solid #747474;
    width: 300px;
    padding: 0px;
    display: grid;
    grid-template-columns: 25px 40px auto;
    border-radius: 10px;


    div.enterprisenumber.error
    border: 1px solid #ff0000;


    div.enterprisenumber>span
    grid-column: 1;
    border: 0px;
    padding: 5px;
    background: linear-gradient(to right, rgba(0,0,0, 0.8) 33%, rgba(255,243,54, 0.8) 33%, rgba(255, 243, 54, 0.8) 66%, rgba(255, 15, 33, 0.8) 66%, rgba(255, 15, 33, 0.8) 100%);
    color: #ffffff;
    font-weight: bold;
    text-shadow: 1px 1px #000000;
    border-radius: 10px 10px 10px 10px;


    div.enterprisenumber>select
    grid-column: 2;
    border: 0px;
    padding: 5px;


    div.enterprisenumber>input
    grid-column: 3;
    border: 0px;
    padding: 5px;
    border-radius: 0px 10px 10px 0px;

    Enter: 844256524
    <div class="enterprisenumber">
    <span>BE</span><select><option value="0">0</option><option value="1">1</option><input value="" maxlength="11" />
    </div>





    document.querySelector("div.enterprisenumber > input").addEventListener("keydown", function(e) , true);

    document.querySelector("div.enterprisenumber > input").addEventListener("keyup", function(e) , 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();

    );

    * 
    box-sizing: border-box;
    font-family: tahoma;
    font-size: 10pt;


    div.enterprisenumber
    border: 1px solid #747474;
    width: 300px;
    padding: 0px;
    display: grid;
    grid-template-columns: 25px 40px auto;
    border-radius: 10px;


    div.enterprisenumber.error
    border: 1px solid #ff0000;


    div.enterprisenumber>span
    grid-column: 1;
    border: 0px;
    padding: 5px;
    background: linear-gradient(to right, rgba(0,0,0, 0.8) 33%, rgba(255,243,54, 0.8) 33%, rgba(255, 243, 54, 0.8) 66%, rgba(255, 15, 33, 0.8) 66%, rgba(255, 15, 33, 0.8) 100%);
    color: #ffffff;
    font-weight: bold;
    text-shadow: 1px 1px #000000;
    border-radius: 10px 10px 10px 10px;


    div.enterprisenumber>select
    grid-column: 2;
    border: 0px;
    padding: 5px;


    div.enterprisenumber>input
    grid-column: 3;
    border: 0px;
    padding: 5px;
    border-radius: 0px 10px 10px 0px;

    Enter: 844256524
    <div class="enterprisenumber">
    <span>BE</span><select><option value="0">0</option><option value="1">1</option><input value="" maxlength="11" />
    </div>






    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Mar 7 at 17:49

























    answered Mar 4 at 19:55









    MouserMouser

    11.6k22148




    11.6k22148












    • Wow! Thanks for the explanation. I like the solution. However the modulo test is gone to check if the number is valid (The first 7 digits without the 0 or 1 in front, %97 should be the last two digits).

      – Thore
      Mar 4 at 21:44











    • that's not that difficult, but not doable in the regexp though.

      – Mouser
      Mar 4 at 22:33






    • 2





      See the solutions posted in my answer. Modulo check should be done separately.

      – Mouser
      Mar 4 at 23:10







    • 1





      Reworked the entire rexexp. Should hopefully meet your expectations. Mouser out.

      – Mouser
      Mar 5 at 0:51






    • 1





      s*? really should just be s*. The extra laziness gains us nothing, and just causes more backtracking on valid inputs.

      – amalloy
      Mar 5 at 1:01

















    • Wow! Thanks for the explanation. I like the solution. However the modulo test is gone to check if the number is valid (The first 7 digits without the 0 or 1 in front, %97 should be the last two digits).

      – Thore
      Mar 4 at 21:44











    • that's not that difficult, but not doable in the regexp though.

      – Mouser
      Mar 4 at 22:33






    • 2





      See the solutions posted in my answer. Modulo check should be done separately.

      – Mouser
      Mar 4 at 23:10







    • 1





      Reworked the entire rexexp. Should hopefully meet your expectations. Mouser out.

      – Mouser
      Mar 5 at 0:51






    • 1





      s*? really should just be s*. The extra laziness gains us nothing, and just causes more backtracking on valid inputs.

      – amalloy
      Mar 5 at 1:01
















    Wow! Thanks for the explanation. I like the solution. However the modulo test is gone to check if the number is valid (The first 7 digits without the 0 or 1 in front, %97 should be the last two digits).

    – Thore
    Mar 4 at 21:44





    Wow! Thanks for the explanation. I like the solution. However the modulo test is gone to check if the number is valid (The first 7 digits without the 0 or 1 in front, %97 should be the last two digits).

    – Thore
    Mar 4 at 21:44













    that's not that difficult, but not doable in the regexp though.

    – Mouser
    Mar 4 at 22:33





    that's not that difficult, but not doable in the regexp though.

    – Mouser
    Mar 4 at 22:33




    2




    2





    See the solutions posted in my answer. Modulo check should be done separately.

    – Mouser
    Mar 4 at 23:10






    See the solutions posted in my answer. Modulo check should be done separately.

    – Mouser
    Mar 4 at 23:10





    1




    1





    Reworked the entire rexexp. Should hopefully meet your expectations. Mouser out.

    – Mouser
    Mar 5 at 0:51





    Reworked the entire rexexp. Should hopefully meet your expectations. Mouser out.

    – Mouser
    Mar 5 at 0:51




    1




    1





    s*? really should just be s*. The extra laziness gains us nothing, and just causes more backtracking on valid inputs.

    – amalloy
    Mar 5 at 1:01





    s*? really should just be s*. The extra laziness gains us nothing, and just causes more backtracking on valid inputs.

    – amalloy
    Mar 5 at 1:01













    2














    For your example strings, you could match:



    ^(?:BEs?)?[01]?(d3([. ])d32d3|d9)$


    That will match




    • ^ Start of string


    • (?:BEs?)? Optional BE followed by optional whitespace char


    • [01]? Optional zero or 1


    • ( Capturing group


      • d3 Match 3 digits


      • ([. ]) Capture in group either a space or digit to use as backreference


      • d32d3 Match 3 digits, dot or space (2 is the backreference) and 3 digits


      • | Or


      • d9 Match 9 digits



    • ) Close capturing group


    • $ End of string

    Regex demo



    And then in the replacement use the first capturing group and replace the space or the dot with an empty string.






    let pattern = /^(?:BEs?)?[01]?(d3([. ])d32d3|d9)$/;
    let strings = [
    "BE 0123.321.123",
    "BE0123.321.123",
    "BE0123 321 123",
    "0123.321.123",
    "123.321.123",
    "123321123",
    ];

    strings = strings.map(x => x.replace(pattern, function(m, g)
    let enterpriseNumber = g.replace(/[. ]/g, "");
    return `BE 0$enterpriseNumber.substring(0, 3).$enterpriseNumber.substring(3, 6).$enterpriseNumber.substring(6, 9)`
    ));

    console.log(strings);








    share|improve this answer





























      2














      For your example strings, you could match:



      ^(?:BEs?)?[01]?(d3([. ])d32d3|d9)$


      That will match




      • ^ Start of string


      • (?:BEs?)? Optional BE followed by optional whitespace char


      • [01]? Optional zero or 1


      • ( Capturing group


        • d3 Match 3 digits


        • ([. ]) Capture in group either a space or digit to use as backreference


        • d32d3 Match 3 digits, dot or space (2 is the backreference) and 3 digits


        • | Or


        • d9 Match 9 digits



      • ) Close capturing group


      • $ End of string

      Regex demo



      And then in the replacement use the first capturing group and replace the space or the dot with an empty string.






      let pattern = /^(?:BEs?)?[01]?(d3([. ])d32d3|d9)$/;
      let strings = [
      "BE 0123.321.123",
      "BE0123.321.123",
      "BE0123 321 123",
      "0123.321.123",
      "123.321.123",
      "123321123",
      ];

      strings = strings.map(x => x.replace(pattern, function(m, g)
      let enterpriseNumber = g.replace(/[. ]/g, "");
      return `BE 0$enterpriseNumber.substring(0, 3).$enterpriseNumber.substring(3, 6).$enterpriseNumber.substring(6, 9)`
      ));

      console.log(strings);








      share|improve this answer



























        2












        2








        2







        For your example strings, you could match:



        ^(?:BEs?)?[01]?(d3([. ])d32d3|d9)$


        That will match




        • ^ Start of string


        • (?:BEs?)? Optional BE followed by optional whitespace char


        • [01]? Optional zero or 1


        • ( Capturing group


          • d3 Match 3 digits


          • ([. ]) Capture in group either a space or digit to use as backreference


          • d32d3 Match 3 digits, dot or space (2 is the backreference) and 3 digits


          • | Or


          • d9 Match 9 digits



        • ) Close capturing group


        • $ End of string

        Regex demo



        And then in the replacement use the first capturing group and replace the space or the dot with an empty string.






        let pattern = /^(?:BEs?)?[01]?(d3([. ])d32d3|d9)$/;
        let strings = [
        "BE 0123.321.123",
        "BE0123.321.123",
        "BE0123 321 123",
        "0123.321.123",
        "123.321.123",
        "123321123",
        ];

        strings = strings.map(x => x.replace(pattern, function(m, g)
        let enterpriseNumber = g.replace(/[. ]/g, "");
        return `BE 0$enterpriseNumber.substring(0, 3).$enterpriseNumber.substring(3, 6).$enterpriseNumber.substring(6, 9)`
        ));

        console.log(strings);








        share|improve this answer















        For your example strings, you could match:



        ^(?:BEs?)?[01]?(d3([. ])d32d3|d9)$


        That will match




        • ^ Start of string


        • (?:BEs?)? Optional BE followed by optional whitespace char


        • [01]? Optional zero or 1


        • ( Capturing group


          • d3 Match 3 digits


          • ([. ]) Capture in group either a space or digit to use as backreference


          • d32d3 Match 3 digits, dot or space (2 is the backreference) and 3 digits


          • | Or


          • d9 Match 9 digits



        • ) Close capturing group


        • $ End of string

        Regex demo



        And then in the replacement use the first capturing group and replace the space or the dot with an empty string.






        let pattern = /^(?:BEs?)?[01]?(d3([. ])d32d3|d9)$/;
        let strings = [
        "BE 0123.321.123",
        "BE0123.321.123",
        "BE0123 321 123",
        "0123.321.123",
        "123.321.123",
        "123321123",
        ];

        strings = strings.map(x => x.replace(pattern, function(m, g)
        let enterpriseNumber = g.replace(/[. ]/g, "");
        return `BE 0$enterpriseNumber.substring(0, 3).$enterpriseNumber.substring(3, 6).$enterpriseNumber.substring(6, 9)`
        ));

        console.log(strings);








        let pattern = /^(?:BEs?)?[01]?(d3([. ])d32d3|d9)$/;
        let strings = [
        "BE 0123.321.123",
        "BE0123.321.123",
        "BE0123 321 123",
        "0123.321.123",
        "123.321.123",
        "123321123",
        ];

        strings = strings.map(x => x.replace(pattern, function(m, g)
        let enterpriseNumber = g.replace(/[. ]/g, "");
        return `BE 0$enterpriseNumber.substring(0, 3).$enterpriseNumber.substring(3, 6).$enterpriseNumber.substring(6, 9)`
        ));

        console.log(strings);





        let pattern = /^(?:BEs?)?[01]?(d3([. ])d32d3|d9)$/;
        let strings = [
        "BE 0123.321.123",
        "BE0123.321.123",
        "BE0123 321 123",
        "0123.321.123",
        "123.321.123",
        "123321123",
        ];

        strings = strings.map(x => x.replace(pattern, function(m, g)
        let enterpriseNumber = g.replace(/[. ]/g, "");
        return `BE 0$enterpriseNumber.substring(0, 3).$enterpriseNumber.substring(3, 6).$enterpriseNumber.substring(6, 9)`
        ));

        console.log(strings);






        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Mar 4 at 21:36

























        answered Mar 4 at 20:30









        The fourth birdThe fourth bird

        24.6k81629




        24.6k81629





















            2














            Here is an implementation of a BE ____.___.___ style of input. The pattern will be maintained, so the input will be guaranteed to have the "BE" prefix, the space, and the two dots. The validation can then concentrate on completeness and the modulo test.



            Note that the input requires the first group to have 4 digits, where the first digit must be a 0 or a 1.






            const ent = document.getElementById("ent");
            const out = document.getElementById("isvalid");

            function format() D+/g;
            const [i, j] = [this.selectionStart, this.selectionEnd].map(i =>
            i = this.value.slice(0, i).replace(re, "").length;
            return i + 3 + (i >= 4 + format.backspace) + (i >= 7 + format.backspace);
            );
            this.value = "BE " + this.value.replace(re, "").padEnd(10, "_")
            .replace(/(....)(...)(...).*/, "$1.$2.$3");
            this.setSelectionRange(i, j);
            format.backspace = false;
            out.textContent = validate(this.value) ? "is valid" : "is invalid";


            function validate(num)
            return /^BE [01](d3.)2d3$/.test(num)
            && 97 - num.replace(/D/g, "").slice(0, 8) % 97 === +num.slice(-2);


            ent.addEventListener("input", format);
            ent.addEventListener("keydown", (e) => format.backspace = e.key == "Backspace");

            Belgian enterprise number: <input id="ent" value="BE ____.___.___">
            <span id="isvalid"></span>








            share|improve this answer























            • Wow, that's a nice solution to the second question.

              – Mouser
              Mar 4 at 23:11















            2














            Here is an implementation of a BE ____.___.___ style of input. The pattern will be maintained, so the input will be guaranteed to have the "BE" prefix, the space, and the two dots. The validation can then concentrate on completeness and the modulo test.



            Note that the input requires the first group to have 4 digits, where the first digit must be a 0 or a 1.






            const ent = document.getElementById("ent");
            const out = document.getElementById("isvalid");

            function format() D+/g;
            const [i, j] = [this.selectionStart, this.selectionEnd].map(i =>
            i = this.value.slice(0, i).replace(re, "").length;
            return i + 3 + (i >= 4 + format.backspace) + (i >= 7 + format.backspace);
            );
            this.value = "BE " + this.value.replace(re, "").padEnd(10, "_")
            .replace(/(....)(...)(...).*/, "$1.$2.$3");
            this.setSelectionRange(i, j);
            format.backspace = false;
            out.textContent = validate(this.value) ? "is valid" : "is invalid";


            function validate(num)
            return /^BE [01](d3.)2d3$/.test(num)
            && 97 - num.replace(/D/g, "").slice(0, 8) % 97 === +num.slice(-2);


            ent.addEventListener("input", format);
            ent.addEventListener("keydown", (e) => format.backspace = e.key == "Backspace");

            Belgian enterprise number: <input id="ent" value="BE ____.___.___">
            <span id="isvalid"></span>








            share|improve this answer























            • Wow, that's a nice solution to the second question.

              – Mouser
              Mar 4 at 23:11













            2












            2








            2







            Here is an implementation of a BE ____.___.___ style of input. The pattern will be maintained, so the input will be guaranteed to have the "BE" prefix, the space, and the two dots. The validation can then concentrate on completeness and the modulo test.



            Note that the input requires the first group to have 4 digits, where the first digit must be a 0 or a 1.






            const ent = document.getElementById("ent");
            const out = document.getElementById("isvalid");

            function format() D+/g;
            const [i, j] = [this.selectionStart, this.selectionEnd].map(i =>
            i = this.value.slice(0, i).replace(re, "").length;
            return i + 3 + (i >= 4 + format.backspace) + (i >= 7 + format.backspace);
            );
            this.value = "BE " + this.value.replace(re, "").padEnd(10, "_")
            .replace(/(....)(...)(...).*/, "$1.$2.$3");
            this.setSelectionRange(i, j);
            format.backspace = false;
            out.textContent = validate(this.value) ? "is valid" : "is invalid";


            function validate(num)
            return /^BE [01](d3.)2d3$/.test(num)
            && 97 - num.replace(/D/g, "").slice(0, 8) % 97 === +num.slice(-2);


            ent.addEventListener("input", format);
            ent.addEventListener("keydown", (e) => format.backspace = e.key == "Backspace");

            Belgian enterprise number: <input id="ent" value="BE ____.___.___">
            <span id="isvalid"></span>








            share|improve this answer













            Here is an implementation of a BE ____.___.___ style of input. The pattern will be maintained, so the input will be guaranteed to have the "BE" prefix, the space, and the two dots. The validation can then concentrate on completeness and the modulo test.



            Note that the input requires the first group to have 4 digits, where the first digit must be a 0 or a 1.






            const ent = document.getElementById("ent");
            const out = document.getElementById("isvalid");

            function format() D+/g;
            const [i, j] = [this.selectionStart, this.selectionEnd].map(i =>
            i = this.value.slice(0, i).replace(re, "").length;
            return i + 3 + (i >= 4 + format.backspace) + (i >= 7 + format.backspace);
            );
            this.value = "BE " + this.value.replace(re, "").padEnd(10, "_")
            .replace(/(....)(...)(...).*/, "$1.$2.$3");
            this.setSelectionRange(i, j);
            format.backspace = false;
            out.textContent = validate(this.value) ? "is valid" : "is invalid";


            function validate(num)
            return /^BE [01](d3.)2d3$/.test(num)
            && 97 - num.replace(/D/g, "").slice(0, 8) % 97 === +num.slice(-2);


            ent.addEventListener("input", format);
            ent.addEventListener("keydown", (e) => format.backspace = e.key == "Backspace");

            Belgian enterprise number: <input id="ent" value="BE ____.___.___">
            <span id="isvalid"></span>








            const ent = document.getElementById("ent");
            const out = document.getElementById("isvalid");

            function format() D+/g;
            const [i, j] = [this.selectionStart, this.selectionEnd].map(i =>
            i = this.value.slice(0, i).replace(re, "").length;
            return i + 3 + (i >= 4 + format.backspace) + (i >= 7 + format.backspace);
            );
            this.value = "BE " + this.value.replace(re, "").padEnd(10, "_")
            .replace(/(....)(...)(...).*/, "$1.$2.$3");
            this.setSelectionRange(i, j);
            format.backspace = false;
            out.textContent = validate(this.value) ? "is valid" : "is invalid";


            function validate(num)
            return /^BE [01](d3.)2d3$/.test(num)
            && 97 - num.replace(/D/g, "").slice(0, 8) % 97 === +num.slice(-2);


            ent.addEventListener("input", format);
            ent.addEventListener("keydown", (e) => format.backspace = e.key == "Backspace");

            Belgian enterprise number: <input id="ent" value="BE ____.___.___">
            <span id="isvalid"></span>





            const ent = document.getElementById("ent");
            const out = document.getElementById("isvalid");

            function format() D+/g;
            const [i, j] = [this.selectionStart, this.selectionEnd].map(i =>
            i = this.value.slice(0, i).replace(re, "").length;
            return i + 3 + (i >= 4 + format.backspace) + (i >= 7 + format.backspace);
            );
            this.value = "BE " + this.value.replace(re, "").padEnd(10, "_")
            .replace(/(....)(...)(...).*/, "$1.$2.$3");
            this.setSelectionRange(i, j);
            format.backspace = false;
            out.textContent = validate(this.value) ? "is valid" : "is invalid";


            function validate(num)
            return /^BE [01](d3.)2d3$/.test(num)
            && 97 - num.replace(/D/g, "").slice(0, 8) % 97 === +num.slice(-2);


            ent.addEventListener("input", format);
            ent.addEventListener("keydown", (e) => format.backspace = e.key == "Backspace");

            Belgian enterprise number: <input id="ent" value="BE ____.___.___">
            <span id="isvalid"></span>






            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Mar 4 at 22:50









            trincottrincot

            130k1691125




            130k1691125












            • Wow, that's a nice solution to the second question.

              – Mouser
              Mar 4 at 23:11

















            • Wow, that's a nice solution to the second question.

              – Mouser
              Mar 4 at 23:11
















            Wow, that's a nice solution to the second question.

            – Mouser
            Mar 4 at 23:11





            Wow, that's a nice solution to the second question.

            – Mouser
            Mar 4 at 23:11

















            draft saved

            draft discarded
















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid


            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.

            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54990565%2fcan-this-function-be-rewritten-with-a-regex%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown






            Popular posts from this blog

            How to check contact read email or not when send email to Individual?

            Displaying single band from multi-band raster using QGIS

            How many registers does an x86_64 CPU actually have?