这个正则表达式有什么问题?JSLint 抛出了一个错误。

3

我正试图通过新版的JSLint来验证我的整个脚本但是遇到了这个问题:

function a() {
    'use strict';
    var string;
    string = string.replace(/\x00*/g, '');
}

它抛出以下异常:

Unexpected 'x' after '\'.

string = string.replace(/\x00*/g, '');

旧版本在这方面没有报错,虽然我知道这是beta版,但我期望它的工作效果应该和旧版本一样好。\x00代表null字符。

那么,这是ECMAScript 6的变化吗?还是只是JSLint的错误?我真的做错了什么吗?


使用 /[\x00]*/g 没有出现错误。 - Deadooshka
是的,我已经注意到了。没有使用方括号指定正则表达式字符是错误的吗? - WilliamTheBaker
@WilliamTheBaker—不行。你也可以使用/\u0000/(JSLint似乎喜欢这个)因为ECMA-262明确允许四位十六进制值,而像\x00这样的两位数值则不行(据我所知)。然而,这会抛出一个错误:“null不是一个对象”,你必须使用/\u0000*/ - RobG
谢谢。根据@nhahtdh的说法,这是允许的。因此,\0\u0000\x00都是有效的。我肯定会使用\u0000,只是因为我希望验证器能够继续通过我的代码,但也许可以在Github上提出问题以了解Douglas的意见。 - WilliamTheBaker
2个回答

3
当JSLint,JSHint(版本1.0.0之前)或ESLint遇到以=字符开头的正则表达式文字时,会抛出“正则表达式字面值可能与'/ ='混淆”的错误。在以下示例中,我们尝试将一个正则表达式字面量分配给变量x以匹配字符串“= 1”:
引发此错误是为了突出可能令人困惑的代码片段。如果您不修复此错误,您的代码将运行良好,但对其他人来说可能会令人困惑,特别是对于快速搜索脚本的人来说,乍一看可能会令人困惑。
在JavaScript中,“/”字符是有歧义的。它可以表示正则表达式字面量的开始或结束,就像上面的例子一样,也可以被解释为除法运算符。像大多数算术运算符一样,除法运算符可以与赋值运算符组合使用以产生简写形式:

https://jslinterrors.com/a-regular-expression-literal-can-be-confused-with

所以您需要使用RegExp构造函数:

string.replace(new RegExp('\\x00*', 'g'), '');

这将输出与正则表达式字面量相同的正则表达式:

console.log(new RegExp('\\x00*', 'g').toString() === /\x00*/g.toString()); // true

提示

空字符\x00可以缩写为\0MDN文档

new RegExp('\\0*', 'g')

--

更新

@nhahtdh的回答展示了可以使用/\u0000*/g字面量。


现在它显示为 0意外的 '\' 后面有 '0'。 但问题仍然存在。 - Siguza
我通过命令行jslint工具运行它,没有收到错误。 - Miguel Mota
1
你是否通过 http://jslint.com 或 http://old.jslint.com 运行它?前者可以验证它。 - WilliamTheBaker
@RobG,是的,我不明白为什么会这样。旧版的JSLint认可这种语法,而且它们基本上是一样的。这也很奇怪,因为正如@Deadooshka指出的那样,/[\x00]*/g没有抛出任何错误,并且没有使用Regex构造函数。我觉得这样更正确,因为方括号用于包含字符,而空字符是一个字符,但是我以为在没有方括号的情况下指定一个字符仍然是有效的正则表达式? - WilliamTheBaker
@WilliamTheBaker 嗯,我不知道该说什么,看起来新的 JSLint 有一些奇怪的漏洞。在我看来,JSHint 是更好的选择,因为它是由社区贡献而成,而不是一个人的作品。 - Miguel Mota
显示剩余15条评论

1
根据ECMAScript规范:
  • \x00 is valid, under the grammar expansion:

    Atom -> \ AtomEscape
    AtomEscape -> CharacterEscape
    CharacterEscape -> HexEscapeSequence
    HexEscapeSequence -> x HexDigit HexDigit
    

    and the pattern semantic:

    The production CharacterEscape :: HexEscapeSequence evaluates by evaluating the CV of the HexEscapeSequence (see 7.8.4) and returning its character result.

  • \0 is always interpreted as matching the NUL character, under the pattern semantic of DecimalEscape:

    The production DecimalEscape :: DecimalIntegerLiteral [lookahead ∉ DecimalDigit] evaluates as follows:

    1. Let i be the MV of DecimalIntegerLiteral.
    2. If i is zero, return the EscapeValue consisting of a <NUL> character (Unicode value 0000).
    3. Return the EscapeValue consisting of the integer i.

    The definition of "the MV of DecimalIntegerLiteral" is in 7.8.3.

    NOTE If \ is followed by a decimal number n whose first digit is not 0, then the escape sequence is considered to be a backreference. It is an error if n is greater than the total number of left capturing parentheses in the entire regular expression. \0 represents the <NUL> character and cannot be followed by a decimal digit.

因此,我不确定为什么JSLint禁止这些结构。从一些测试来看,似乎它们没有在解析器中实现,因为像这样的简单代码:
var x = /(['"])\1/;

抛出错误 "Unexpected '1' after '\'."

如果您想使代码通过 JSLint,可以使用 \u0000 指定 NUL 字符。否则,您可以忽略此错误。


我认为这个解释已经很好了。因此,可以假设它要么是解析器中的错误,要么还没有实现,因为它处于测试版阶段。你在 ECMA 的文档中找到了吗?如果不麻烦的话,能给我链接吗?我不能忽略它,因为解析器会停在那里而不继续执行,所以我想我只能同时使用 \u0000。谢谢! - WilliamTheBaker
@WilliamTheBaker:引用的文本来自文档。您可以在此处找到规范:http://www.ecma-international.org/ecma-262/5.1/ - nhahtdh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接