4

I am working in angular 7 and validating contact number using

"^(?!(\d)\1+$)(?:\(?\+\d{1,3}\)?[- ]?|0)?\d{10}$"

regular expression but it is throwing the following error : Module parse failed: Octal literal in strict mode (10:76)

I have already tried \\ instead of \ because as per my finding the problem is with \ character.

registerForm = this.fb.group(
{
  email:['', [Validators.required, Validators.pattern('^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+.[a-zA-Z0-9-.]+.com$')]],
  contact:['',[Validators.required, Validators.pattern('/^(?!(\d)\1+$)(?:\(?\+\d{1,3}\)?[- ]?|0)?\d{10}$/')]],
  password:['',[Validators.required]],
  confirmPassword:['',[Validators.required]]
},{ validator: PasswordMatchValidator });

Is there any way to replace \ character to make it work?

msanford
  • 11,803
  • 11
  • 66
  • 93
Mariah
  • 129
  • 1
  • 10

4 Answers4

8

This is an X-Y Problem. Everyone is focusing on your original question title, which asked about escaping literal \ in a regex. That's not the problem.

First, in JavaScript, numbers can be represented many ways. One of those is octal literal notation, indicated by prefixing a number (character code) with a \.

Your regex contains \1 which is being interpreted as an octal, which is your error message. Octal escape sequences have been deprecated which is why strictmode throws an error, which is the actual problem you're facing.

If you have resolved the compile error by escaping your \1 as \\1, you have generated this expression parsing which executes a negative look-ahead of any single digit, followed by a literal "\" character, followed by the number "1" any number of times.

railroad diagram of a completely broken phone number validator

You'll also notice that the area code parentheses are optional, but it requires a literal + (because it's escaped as \+) after the opening bracket. That's certainly not what you want.

The regex you want is probably the one of the answers from this question

"^(\+\d{1,2}\s)?\(?\d{3}\)?[\s.-]?\d{3}[\s.-]?\d{4}$"

which parses to this

railroad diagram of a fairly good phone number validator

Second, Angular's PatternValidator converts a string to a regular expression, so just pass in a string without bracketing it with forward slashes.

msanford
  • 11,803
  • 11
  • 66
  • 93
  • 1
    This helpful in terms of finding a working pattern but (ironically given your opening criticism) you've just forgotten to deal with escaping backslashes (not in the pattern but in the string), which you would need to do when passing this pattern in as a string literal. `Validators.pattern('(\\+\\d{1,2}\\s)?\\(?\\d{3}\\)?[\\s.-]?\\d{3}[\\s.-]?\\d{4}')` Or (neater IMO) `Validators.pattern(/^(\+\d{1,2}\s)?\(?\d{3}\)?[\s.-]?\d{3}[\s.-]?\d{4}$/)` – Rob Hogan Jun 02 '19 at 10:37
  • 1
    Indeed, the octal error is seen precisely because the `\1` wasn't correctly escaped to `\\1` inside a string literal. This would've resulted in a `\1+` in the regex pattern, which is not a repeated literal 1 but a repetition of the first matching group. – Rob Hogan Jun 02 '19 at 11:02
0

The following regular expressions will allow you to match or replace backslashes:

/\\/ // (1) matches one backslash (the 1st occurrence only)

/\\/g // (2) matches any occurrence of backslash (global search)

re1 = new RegExp("\\\\","") // same as (1), with RegExp constructor

re2 = new RegExp("\\\\","g") // same as (2), with RegExp constructor

based on this article.

According to Angular docs, the Validators.pattern method is accepting string | RegExp. In your case it converts the string to RegExp before using it. Therefore, you would need \\\\ backslashes to get a regular \ backslash.

Community
  • 1
  • 1
Rov
  • 133
  • 1
  • 11
  • I have tried \\\\ but it dint work for me ... whereas i couldnt understand the sense of article unfortunately. – Mariah Jun 01 '19 at 22:37
  • @Mariah Seems that your second pattern has issues, please remove ```/``` from the beginning and the end of ```'/^(?!(\d)\1+$)(?:\(?\+\d{1,3}\)?[- ]?|0)?\d{10}$/'```. The `/` character is not required as explained in [this](https://stackoverflow.com/questions/42392373/angular-2-validators-pattern-not-working) SO question. – Rov Jun 01 '19 at 22:42
0

There are a few problems here but I'd start with this one: The / character is used to start and end a RegExp literal in javascript, it isn't part of the pattern. You shouldn't put it inside quotes (as a string literal) because then angular will incorrectly try to make a pattern which includes the /s.

Instead of:

Validators.pattern('/^(?!(\d)\1+$)(?:\(?\+\d{1,3}\)?[- ]?|0)?\d{10}$/')

Remove your string single quotes:

Validators.pattern(/^(?!(\d)\1+$)(?:\(?\+\d{1,3}\)?[- ]?|0)?\d{10}$/)

I'm pretty sure this still isn't the regex you want, it looks like you're escaping parentheses you shouldn't be, but it is at least valid.

Where did you get the pattern from originally? If you share that we might be able to sort it out, or try playing around on https://regexr.com and when you get the pattern right just copy it straight in as you see it there, no quotes or additional escaping.

(Confusingly, Validators.pattern also accepts strings, but if you want to pass a string you should omit the /, because those forward slashes are not actually part of the pattern, and you should also omit ^ and $ when passing a string because Angular adds them automatically)

Side note: Validating phone numbers with regex is probably a bad idea anyway. Google libphonenumber

Rob Hogan
  • 2,442
  • 19
  • 23
0

Actually you can use \1 if you use a literal declaration (without quotes)

const regex = /someregex\1/gm;
Yohan Dahmani
  • 1,670
  • 21
  • 33