0

I am trying to match all UK phone numbers in a string.

The pattern for this is:

^\(?(?:(?:0(?:0|11)\)?[\s-]?\(?|\+)44\)?[\s-]?\(?(?:0\)?[\s-]?\(?)?|0)(?:\d{2}\)?[\s-]?\d{4}[\s-]?\d{4}|\d{3}\)?[\s-]?\d{3}[\s-]?\d{3,4}|\d{4}\)?[\s-]?(?:\d{5}|\d{3}[\s-]?\d{3})|\d{5}\)?[\s-]?\d{4,5}|8(?:00[\s-]?11[\s-]?11|45[\s-]?46[\s-]?4\d))(?:(?:[\s-]?(?:x|ext\.?\s?|\#)\d+)?)$

But when I try to initiate a new RegExp like:

const myRegex = RegExp('^\(?(?:(?:0(?:0|11)\)?[\s-]?\(?|\+)44\)?[\s-]?\(?(?:0\)?[\s-]?\(?)?|0)(?:\d{2}\)?[\s-]?\d{4}[\s-]?\d{4}|\d{3}\)?[\s-]?\d{3}[\s-]?\d{3,4}|\d{4}\)?[\s-]?(?:\d{5}|\d{3}[\s-]?\d{3})|\d{5}\)?[\s-]?\d{4,5}|8(?:00[\s-]?11[\s-]?11|45[\s-]?46[\s-]?4\d))(?:(?:[\s-]?(?:x|ext\.?\s?|\#)\d+)?)$','g');

I get this error:

Uncaught SyntaxError: Invalid regular expression: /^(?(?:(?:0(?:0|11))?[s-]?(?|+)44)?[s-]?(?(?:0)?[s-]?(?)?|0)(?:d{2})?[s-]?d{4}[s-]?d{4}|d{3})?[s-]?d{3}[s-]?d{3,4}|d{4})?[s-]?(?:d{5}|d{3}[s-]?d{3})|d{5})?[s-]?d{4,5}|8(?:00[s-]?11[s-]?11|45[s-]?46[s-]?4d))(?:(?:[s-]?(?:x|ext.?s?|#)d+)?)$/: Invalid group

mplungjan
  • 169,008
  • 28
  • 173
  • 236
mo.dhouibi
  • 565
  • 1
  • 4
  • 18
  • 1
    My question to you is **why?** Why did you decide to use regex for this? This seems overly convoluted. What is your end goal? I think if you provide us with samples of what you want to match and not match we can provide you with a better response/answer. Personally, I don't think the regex is well-formed or should be used exclusively in your case. It seems you have rules that you have added to your regex, just capture those sections and then test them for certain values. – ctwheels Apr 30 '18 at 16:56
  • 2
    So the regex may be correct, regex101 does not complain. HOWEVER it is an invalid JavaScript regex due to the unescaped slashes - they are not needed in `/....\..../` instead of a string – mplungjan Apr 30 '18 at 16:57
  • 1
    Unlike literal regex, you need to escape properly in the `RegExp` constructor, as strings have escape too - that results in double escaping things, e.g. `\\(`. – ASDFGerte Apr 30 '18 at 16:57
  • See [Regular expression for UK based and only numeric phone number in cakephp](https://stackoverflow.com/questions/11518035/regular-expression-for-uk-based-and-only-numeric-phone-number-in-cakephp) – ctwheels Apr 30 '18 at 17:00
  • @ctwheels: That doesn't answer the question "Why this is an invalid regular expression?" . – Felix Kling Apr 30 '18 at 17:01
  • @FelixKling I realized that after I posted it. You beat me to changes and retracted close vote. I'm positive there's a dupe out there though, waiting for Wiktor to find it. – ctwheels Apr 30 '18 at 17:02
  • @ctwheels: There certainly are a lot of questions about string literals + regular expression + escape characters ;) – Felix Kling Apr 30 '18 at 17:15
  • JS is backwards compatible with it's dire past.. that is the single quoted string literal interpolates control escapes like `\x20` and `\n` emanating from double quoted C++ strings. Ie. 3 \\\ or 2 \\ evaluate to 1 \. And 1 \ evaluates to 0 if it's not a control code type. So just pretend it's a double quoted string. Which is a somewhat different set of rules for single quoted strings used in most macro lang's. –  Apr 30 '18 at 20:12

1 Answers1

4

The error already shows you what the problem is. \ inside a string literal is the escape character. But escaping a character that doesn't need to be escaped simply "drops" the \:

console.log('\(');

So the value you are passing to the regular expression engine (and what the error shows you) is:

^(?(?...

(note: no backslash)

and (?( is not a valid character sequence in a regular expression.

You either have to

Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
  • I have tried to escape the escape : new RegExp("^\\\(?(?:(?:0(?:0|11)\)?[\s ...etc But this gives the same error – mo.dhouibi Apr 30 '18 at 17:11
  • You'd have to escape **all** escape characters of course. But using an regular expression literal would be a lot easier. – Felix Kling Apr 30 '18 at 17:14
  • Might as well say it uses the same rules as a double quoted string and be done with it. –  Apr 30 '18 at 19:51
  • @sln: not sure I understand... – Felix Kling Apr 30 '18 at 19:52
  • Yeah, you know "\\a" = "\\\a" = '\\a' = '\\\a' and "\n" = '\n' = newline, and "\x20" = '\x20' = space. –  Apr 30 '18 at 19:55
  • @sln: this is not about single vs double quotes. If you don’t know how escaping in strings works or that there are two levels of escaping (string, regular expression), then saying “it works like in any other string literal” is not helpful. – Felix Kling Apr 30 '18 at 19:58
  • You read more than I said... –  Apr 30 '18 at 19:59
  • You are still using a string literal, this time even without any escaping. Write this:`var myRegex = /.../;` and replace `...` with what you inside the quotation marks in your question. That’s all you need. No `RegExp`. Make sure to read the arrow I linked to. – Felix Kling May 01 '18 at 14:34