在放入正则表达式之前应该转义的所有字符的列表?

能否有人给出一个完整的特殊字符列表,应该转义?

恐怕有些我不认识。

61340 次浏览

根据 这个网站,要转义的字符列表是

[ ,反斜杠,插入符号 ^ ,美元符号 $,句点或点。,垂直条或管道符号 | ,问号?星号 * ,加号 + ,开始圆括号(和结束圆括号)。

除此之外,还需要转义被 Javascript 解释器解释为字符串末尾的字符,即 '"

看看 PHP.JS 对 PHP 的 preg_quote函数的实现,它应该可以满足您的需要:

Http://phpjs.org/functions/preg_quote:491

特殊的正则表达式字符是: . \ + * ? [ ^ ] $ ( ) { } = ! < > | : -

在字符集中,为了匹配字面连字符 -,如果没有定位在开始或结束处,则需要转义该字符集。例如,给定下列模式中最后一个连字符的位置,需要对其进行转义:

[a-z0-9\-_]+

但它不需要在这里逃脱:

[a-z0-9_-]+

如果没有转义连字符,引擎将尝试将其解释为介于前一个字符和下一个字符之间的范围(就像 a-z匹配介于 a 和 z 之间的任何字符一样)。

此外,/不会在字符集内转义(尽管它们在字符集外需要转义 )。因此,以下语法是有效的;

const pattern = /[/]/;

基于 Tatu Ulmanen 的回答,我在 C # 中的解决方案采用了以下形式:

private static List<string> RegexSpecialCharacters = new List<string>
{
"\\",
".",
"+",
"*",
"?",
"[",
"^",
"]",
"$",
"(",
")",
"{",
"}",
"=",
"!",
"<",
">",
"|",
":",
"-"
};




foreach (var rgxSpecialChar in RegexSpecialCharacters)
rgxPattern = input.Replace(rgxSpecialChar, "\\" + rgxSpecialChar);

注意,我已经切换了’和’的位置如果不能首先处理这些斜线,那么将会导致这些斜线加倍

剪辑

Here is a javascript translation

var regexSpecialCharacters = [
"\\", ".", "+", "*", "?",
"[", "^", "]", "$", "(",
")", "{", "}", "=", "!",
"<", ">", "|", ":", "-"
];


regexSpecialCharacters.forEach(rgxSpecChar =>
input = input.replace(new RegExp("\\" + rgxSpecChar,"gm"), "\\" +
rgxSpecChar))

我正在寻找这个列表关于 ESLint 的“没有无用的逃逸”设置为 reg-ex。并且发现,在 JS 中,对于正则表达式,所提到的这些字符中的一些不需要转义。另一个答案中较长的列表是 PHP,它确实需要转义额外的字符。

ESLint 的这个 github 问题中,大约一半的时候,用户 not-an-aardvark解释了为什么问题中引用的字符是一个可能应该转义的字符。

在 javascript 中,需要转义的字符是 语法特征,或者下列字符之一:

^ $ \ . * + ? ( ) [ ] { } |

对于上面我链接到的 github 问题的响应包括关于“附件 B”语义的解释(我对此知之甚少) ,该语义允许上面提到的4个字符取消转义: ) ] { }

Another thing to note is that escaping a character that doesn't require escaping won't do any harm (except maybe if you're trying to escape the escape character). So, my personal rule of thumb is: "When in doubt, escape"

问题是:

const character = '+'
new RegExp(character, 'gi') // error

聪明的解决方案:

// with babel-polyfill
// Warning: will be removed from babel-polyfill v7
const character = '+'
const escapeCharacter = RegExp.escape(character)
new RegExp(escapeCharacter, 'gi') // /\+/gi


// ES5
const character = '+'
const escapeCharacter = escapeRegExp(character)
new RegExp(escapeCharacter, 'gi') // /\+/gi


function escapeRegExp(string){
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
}

随着在 JavaScript 中引入 Unicode 正则表达式(即用 u标志构造的正则表达式) ,这里的答案变得有点复杂。特别是:

  • 非 unicode 正则表达式支持“ Identity”转义; 也就是说,如果一个字符在正则表达式模式中没有特殊的解释,那么转义什么也不做。这意味着 /a//\a/将以相同的方式匹配。

  • Unicode 正则表达式更为严格——试图转义不被视为“特殊”的字符是一个错误。例如,/\a/u不是有效的正则表达式。

可以从 ECMAScript 标准推断出特殊解释的字符集; 例如,对于 ECMAScript 2021,https://262.ecma-international.org/12.0/#sec-patterns,我们可以看到以下“语法”字符:

SyntaxCharacter :: one of
^ $ \ . * + ? ( ) [ ] { } |

特别是,与其他答案相比,请注意,!<>:-不被认为是语法字符。相反,这些字符可能只在特定的上下文中有特殊的解释。

例如,<>字符只有在用作捕获组名时才有特殊的解释; 例如,在

/(?<name>\w+)/

由于 <>不被认为是语法字符,因此在 unicode 正则表达式中转义它们是一个错误。

> /\</
/\</


> /\</u
Uncaught SyntaxError: Invalid regular expression: /\</: Invalid escape

此外,-字符仅在字符类中进行特殊解释,当用于表示字符范围时,例如。

/[a-z]/

对于 unicode 正则表达式,在字符类内转义 -是有效的,但不能在字符类外转义 -

> /\-/
/\-/


> /\-/u
Uncaught SyntaxError: Invalid regular expression: /\-/: Invalid escape


> /[-]/
/[-]/


> /[\-]/u
/[\-]/u

对于使用 / /语法(相对于 new RegExp())构造的正则表达式,内部斜杠(/)需要转义,但是这对于 JavaScript 解析器而不是正则表达式本身是必需的,以避免模式的结束标记 /与模式中的文字 /之间的模糊性。

> /\//.test("/")
true


> new RegExp("/").test("/")
true

但是最终,如果您的目标是转义字符,这样它们就不会在正则表达式中进行特殊解释,那么只转义语法字符就足够了。例如,如果我们想匹配字符串 (?:hello),我们可以使用:

> /\(\?:hello\)/.test("(?:hello)")
true


> /\(\?:hello\)/u.test("(?:hello)")
true

注意,:字符没有转义。似乎有必要转义 :字符,因为它在模式 (?:hello)中有特殊的解释,但是因为它不被认为是语法字符,所以转义它是不必要的。(转义前面的 (?字符就足以确保 :不会被特殊解释。)


上面的代码片段用以下方法进行了测试:

$ node -v
v16.14.0


$ node -p process.versions.v8
9.4.146.24-node.20