Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do regex constructors need to be double escaped?

In the regex below, \s denotes a space character. I imagine the regex parser, is going through the string and sees \ and knows that the next character is special.

But this is not the case as double escapes are required.

Why is this?

var res = new RegExp('(\\s|^)' + foo).test(moo);

Is there a concrete example of how a single escape could be mis-interpreted as something else?

like image 385
Smurfette Avatar asked Jul 25 '13 15:07

Smurfette


People also ask

Do you need to escape regex?

In order to use a literal ^ at the start or a literal $ at the end of a regex, the character must be escaped. Some flavors only use ^ and $ as metacharacters when they are at the start or end of the regex respectively. In those flavors, no additional escaping is necessary. It's usually just best to escape them anyway.

What is escape sequence in regex?

Escape Sequences (\char): To match a character having special meaning in regex, you need to use a escape sequence prefix with a backslash ( \ ). E.g., \. matches "." ; regex \+ matches "+" ; and regex \( matches "(" . You also need to use regex \\ to match "\" (back-slash).


4 Answers

You are constructing the regular expression by passing a string to the RegExp constructor.

\ is an escape character in string literals.

The \ is consumed by the string literal parsing…

const foo = "foo";
const string = '(\s|^)' + foo;
console.log(string);

… so the data you pass to the RegEx compiler is a plain s and not \s.

You need to escape the \ to express the \ as data instead of being an escape character itself.

like image 75
Quentin Avatar answered Oct 23 '22 07:10

Quentin


Inside the code where you're creating a string, the backslash is a javascript escape character first, which means the escape sequences like \t, \n, \", etc. will be translated into their javascript counterpart (tab, newline, quote, etc.), and that will be made a part of the string. Double-backslash represents a single backslash in the actual string itself, so if you want a backslash in the string, you escape that first.

So when you generate a string by saying var someString = '(\\s|^)', what you're really doing is creating an actual string with the value (\s|^).

like image 42
Joe Enos Avatar answered Oct 23 '22 08:10

Joe Enos


The Regex needs a string representation of \s, which in JavaScript can be produced using the literal "\\s".

Here's a live example to illustrate why "\s" is not enough:

alert("One backslash:          \s\nDouble backslashes: \\s");

Note how an extra \ before \s changes the output.

like image 11
Cristian Lupascu Avatar answered Oct 23 '22 06:10

Cristian Lupascu


\ is used in Strings to escape special characters. If you want a backslash in your string (e.g. for the \ in \s) you have to escape it via a backslash. So \ becomes \\ .

EDIT: Even had to do it here, because \\ in my answer turned to \.

like image 7
schlicht Avatar answered Oct 23 '22 07:10

schlicht