Home > front end >  Why regex working in javascript but not as HTML5 pattern
Why regex working in javascript but not as HTML5 pattern

Time:08-17

The following JS regex is working as expected

/^(?:(?:\(?(?:00|\ )([1-4]\d\d|[1-9]\d )\)?)[\-\.\ \\\/]?)?((?:\(?\d{1,}\)?[\-\.\ \\\/]?){0,})(?:[\-\.\ \\\/]?(?:#|ext\.?|extension|x)[\-\.\ \\\/]?(\d ))?$/i

But when I use this as a HTML 5 pattern I got this error:

Pattern attribute value /^(?:(?:(?(?:00| )([1-4]dd|[1-9]d ))?)[-. \/]?)?((?:(?d{1,})?[-. \/]?){0,})(?:[-. \/]?(?:#|ext.?|extension|x)[-. \/]?(d ))?$/i is not a valid regular expression: Uncaught SyntaxError: Invalid regular expression: //^(?:(?:(?(?:00| )([1-4]dd|[1-9]d ))?)[-. \/]?)?((?:(?d{1,})?[-. \/]?){0,})(?:[-. \/]?(?:#|ext.?|extension|x)[-. \/]?(d ))?$/i/: Invalid group

The browser telling me this "Uncaught SyntaxError: Invalid regular expression. Invalid group"

Any help would be really appreciated as regex is not my real strength.

CodePudding user response:

JS Regex input as copied from example:


/^(?:(?:\(?(?:00|\ )([1-4]\d\d|[1-9]\d )\)?)[\-\.\ \\\/]?)?((?:\(?\d{1,}\)?[\-\.\ \\\/]?){0,})(?:[\-\.\ \\\/]?(?:#|ext\.?|extension|x)[\-\.\ \\\/]?(\d ))?$/i

HTML5 Regex error output as copied from example:


//^(?:(?:(?(?:00| )([1-4]dd|[1-9]d ))?)[-. \/]?)?((?:(?d{1,})?[-. \/]?){0,})(?:[-. \/]?(?:#|ext.?|extension|x)[-. \/]?(d ))?$/i/

From the look of it, javascript is reading your backslashes as if they were escaping characters.

From JS example to HTML error:

  • \d\d becomes dd

  • Any single backslash without a recognized escape character like d, another backslash, etc. just gets deleted.

There are more examples if you look through the input and the resulting error.

If you are using JS to pass this pattern to the html DOM as a string, you need to escape the backslashes. Anytime your pattern needs a backslash, you need to put 2 of them in the string. The first backslash tells the interpreter that the second backslash is a part of the text and not an escape sequence. If the pattern is stored in a tag, like your example, and you are accessing it with JS, you would still want to escape escape your \ by replacing them with \\.

CodePudding user response:

A regex and a regex string are two different things.

Regex example:

/[a-zA-Z\d] /.test('abc123')

Equivalent regex string example:

new RegExp('[a-zA-Z\\d] ').test('abc123')

A backslash in a string escapes the character that follows. For many characters it is a no-op, as in a '\d' string, which is equivalent to 'd'. Hence you need to specify a double backslash to get \d that can be used in a regex string to mean a digit.

Example use in HTML5 to validate an input:

<input type="text" name="uname" pattern="[a-zA-Z\d] " minlength="4" maxlength="10" />

So in your case, make sure to escape the backslash in the regex string:

"^(?:(?:\\(?(?:00|\\ )...

In the pattern attribute you can't specify the modifier i to ignore case, e.g. you need to tweak the regex string itself to be case insensitive.

Docs on HTML pattern attribute: https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/pattern

  • Related