Search code examples
javascriptregexregex-group

Is there a regex that will put 10 digits (usually non-consecutive) into a named capturing group?


I have a user input string that is supposed to contain at least 10 digits but they may be non-consecutive. Of these possible user inputs:

"What is 12? Can we 345 the loan to 678-90"
">>123456789--0"
"1234567890541112144847-909"
"Maybe try 123456 with 7890 too"

I want a regex to give me match.groups.anyTen = '1234567890'.

I have tried /\d+/g but I cannot combine the matches into a single named group. /(?<anyTen>\d+/g only names the first match of consecutive digits.

Other failures:

/(?<anyTen>\d\D*\d\D*\d\D*\d\D*\d\D*\d\D*\d\D*\d\D*\d\D*\d\D*)/
/(?<anyTen>\d{1,10})/
/(?<anyTen>\D*(\d\D*){10})/

Solution

  • You can not have a single group that consists of non consecutive matches.

    What you might do is match the first 10 digits, and then remove the non digits from it.

    Note that \D also matches newlines.

    If you want 10 or more digits, the quantifier will become {9,}

    const s = `"What is 12? Can we 345 the loan to 678-90"
    ">>123456789--0"
    "1234567890541112144847-909"
    "Maybe try 123456 with 7890 too"`;
    
    const regex = /^[^\d\n]*(?<anyTen>\d(?:[^\d\n]*\d){9})/gm;
    const result = Array.from(
      s.matchAll(regex), m =>
      m.groups.anyTen.replace(/\D+/g, "")
    );
    console.log(result)

    Another option could be overwriting the value of the groups.anyVal property:

    const s = "What is 12? Can we 345 the loan to 678-90";
    const regex = /^[^\d\n]*(?<anyTen>\d(?:[^\d\n]*\d){9})/;
    const result = regex.exec(s);
    
    if (result) {
      result.groups.anyTen = result.groups.anyTen.replace(/\D+/g, "");
      console.log(result.groups.anyTen);
    }