Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JSHint "Bad or unnecessary escaping." Do double slashes beginning/end matter?

I'm storing some RegExps in an Object as strings, but getting the above error message.

I believe this is because they aren't prefixed with / or suffixed with / - as I'm running them into a new RegExp() constructor, as the script allows users to define RegExps, so I want them all to be dynamic.

var patterns = {
    email: '^[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$',
    url: '[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)',
    number: '^[-+]?[0-9]*\.?[0-9]+$',
    empty: '^\\s*$'
};

There's the above strings.

To fix them I can do this and / / them:

var patterns = {
    email: '/^[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/',
    url: '/[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)/',
    number: '/^[-+]?[0-9]*\.?[0-9]+$',
    empty: '/^\\s*$/'
};

But when called via new RegExp() surely they'll do this (for example):

var reg = new RegExp(patterns.empty);
/**
 * reg = //^\\s*$//
 */

With double slashes. My question as a bit of a RegExp beginner, is do these double slashes matter? Can it be fixed another way. JSHint is complaining because it's not a "real" RegExp.

I can also remove them from strings and store as true RegExps, but again I need them to be dynamic. Any help appreciated.

like image 391
Stephen Jenkins Avatar asked Apr 22 '14 21:04

Stephen Jenkins


1 Answers

The problem is that the backslash character (\) is used both for escaping special characters in string literals (e.g. \n is interpreted as a single newline character, and \\ as a single backslash character), and it's used in escaping special characters in regular expressions.

So when a string literal is used for a regexp, and you need the regexp to see \, you need to escape the backslash and include \\ in the string literal. Specifically, in email you need \\. rather than \.. E.g.

email: '^[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\\.[a-zA-Z0-9-]+)*$'

Alternatively, you could put the regular expressions in /.../ rather than '...' (or '/.../'). Then string literal escaping doesn't apply, and you don't need to double the slashes. E.g.

email: /^[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/

In the latter case, you also don't need new RegExp(patterns.email), since patterns.email is already a RegExp object.

like image 129
DS. Avatar answered Sep 22 '22 21:09

DS.