What's wrong with this regex? JSLint throws an error
I'm trying to test all script through new JSLint , but doing so:
function a() {
'use strict';
var string;
string = string.replace(/\x00*/g, '');
}
It throws out:
Unexpected "x" after "\".
string = string.replace(/\x00*/g, '');
The old version does not cause errors. I realize this is in beta, but I would expect it to work as well as the old version. \x00
denotes, by the way, a null character.
So, has something changed with ECMAScript 6? Is this just a JSLint bug? Am I really doing something wrong?
source to share
As per ECMAScript spec:
-
\x00
acts under the grammar extension:Atom -> \ AtomEscape AtomEscape -> CharacterEscape CharacterEscape -> HexEscapeSequence HexEscapeSequence -> x HexDigit HexDigit
and the semantic pattern:
The work
CharacterEscape :: HexEscapeSequence
is evaluated by evaluating the CVHexEscapeSequence
(see 7.8.4) and returning its symbolic result. -
\0
is always interpreted as matching the NUL character under the template semanticsDecimalEscape
:Production
DecimalEscape :: DecimalIntegerLiteral [lookahead ∉ DecimalDigit]
is assessed as follows:- Let
i
- MVDecimalIntegerLiteral
. - If
i
equal to zero, returnEscapeValue
consisting of a character<NUL>
(Unicode value 0000). - Returns
EscapeValue
consisting of an integeri
.
The definition of "MV of
DecimalIntegerLiteral
" is found in 7.8.3.NOTE If followed
\
by a decimal numbern
whose first digit is not 0, then the escape sequence is considered a backreference. It is an error if there aren
more than the total number of parentheses in the left column in all regexps.\0
represents a character<NUL>
and cannot be followed by a decimal digit. - Let
So I'm not sure why JSLint disallows these constructs. From some of the tests, it seems that they are not implemented in the parser, since such simple codes are:
var x = /(['"])\1/;
throws "Unexpected '1' after '\'."
error.
If you want to get the code to pass JSLint, you can specify the NUL character with \u0000
. Otherwise, you can simply ignore this error.
source to share
"A regex literal can be confused with a '/ =' error when JSLint, JSHint (prior to 1.0.0) or ESLint encounters a regex literal that starts with an = character. In the following example, we try to assign a regex literal to match a string." = 1 "variable x:
This error occurs to highlight a potentially confusing piece of code. Your code will work fine if you don't fix this error, but it might confuse others, especially at first glance someone is looking for your script quickly.
The / is ambiguous in JavaScript. This can mean the start or end of a regular expression literal, as in the example above, or it can be interpreted as the division operator. Like most arithmetic operators, the division operator can be combined with the assignment operator to create an abbreviation:
https://jslinterrors.com/a-regular-expression-literal-can-be-confused-with
So, you need to use the constructor RegExp
:
string.replace(new RegExp('\\x00*', 'g'), '');
Which outputs the same regex as the regex literal:
console.log(new RegExp('\\x00*', 'g').toString() === /\x00*/g.toString()); // true
Advice
NULL character \x00
can be abbreviated to \0
( MDN docs )
new RegExp('\\0*', 'g')
-
Update
@ nhahtdh's answer shows that you can use a literal /\u0000*/g
.
source to share