1

I want to make typescript validation to this: 01-23-456789

I have one for account number :

this.contractForm.controls.account.get('accNum').setValue(val.match(/[0-9]{1,8}/g)?.join('-'))

This is easy because the account numbers look like this :

12345678-12345678-12345678

And I'm not a regex expert unfortunately, and I don't know how to make for this, that I mentioned in my first sentence.

 public businessNumberValidator() {
    return this.contractForm.controls.szerzodo
      .get('businessnum')
      .valueChanges.pipe(
        throttleTime(1),
        tap((val: string) => {
          const char = val.replace(/\D/g, '').split('');
          if (char.length > 2) {
            char.splice(2, 0, '-');
          }
          if (char.length > 5) {
            char.splice(5, 0, '-');
          }

          this.contractForm.controls.szerzodo.get('businessnum').setValue(char.join(''));
        }),
        untilDestroyed(this)
      )
      .subscribe();
  }

and I write this kind of solution, but I want a better one

4
  • Like this? ^\d+(?:-\d+)+$ regex101.com/r/greKgy/1 Commented Nov 11, 2020 at 8:43
  • i don't need the '-' , because i will join the '-', as you see in the example Commented Nov 11, 2020 at 8:54
  • What is your input string? Commented Nov 11, 2020 at 8:56
  • not string number, when i start write this 4444123456, i want to autocomplete the '-', and look like this 44-44-123456 Commented Nov 11, 2020 at 8:59

2 Answers 2

2

You can use

val.replace(/\D+/g,'')
  .replace(/^(\d{1,2})(\d{1,2})?(\d{1,6})?$/, (_,x,y,z) => 
    z ? `${x}-${y}-${z}` : y ? `${x}-${y}` : x)

Here,

  • .replace(/\D+/g,'') - removes all non-digit chars from string
  • ^(\d{1,2})(\d{1,2})?(\d{1,6})?$ - matches 1 or 2 first digits into Group 1 (x variable), next one or two digits are captured into an optional Group 2 (y variable), and then one to six digits are captured into an optional Group 3 (z variable); then if Group 3 matched, the replacement is Group1-Group2-Group3, if Group 2 matched, the replacement is Group1-Group2, else, the replacement is just Group 1 value.

See a JavaScript demo:

function m (val) {
  const char = val.replace(/\D/g, '').split('');
          if (char.length > 2) {
            char.splice(2, 0, '-');
          }
          if (char.length > 5) {
            char.splice(5, 0, '-');
          }
  return char.join("");
}
function m2 (val) {
  return val.replace(/\D+/g,'')
    .replace(/^(\d{1,2})(\d{1,2})?(\d{1,6})?$/, (_,x,y,z) => 
      z ? `${x}-${y}-${z}` : y ? `${x}-${y}` : x)
}
const val = "01-23-456789";

document.body.innerHTML += "<br/>=== Current approach: ===</br>"
for (let i=1; i<=val.length; i++) {
  document.body.innerHTML += m(val.substring(0,i)) + "<br/>";
}
document.body.innerHTML += "<br/>=== New regex approach: ===</br>"
for (let i=1; i<=val.length; i++) {
  document.body.innerHTML += m2(val.substring(0,i)) + "<br/>";
}

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you very muck dude! It worked! And also great explanation!
-1

Use this pattern:

\d{2,6}

See Demo

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.