请问是否能提供需要转义的特殊字符的完整列表?
我担心自己不知道其中的一些。
请问是否能提供需要转义的特殊字符的完整列表?
我担心自己不知道其中的一些。
PHP的preg_quote
函数接受任意字符串,并“在正则表达式语法中的每个字符前面放置反斜杠”,从而转义这些字符:
. \ + * ? [ ^ ] $ ( ) { } = ! < > | : -
以下是JavaScript preg_quote的简化版本,取自Locutus:
function escapeRegexChars(str) {
return str.replace(new RegExp('[.\\\\+*?\\[\\^\\]$(){}=!<>|:\\-]', 'g'), '\\$&')
}
参考Tatu Ulmanen的答案,我的C#解决方案如下:
private static List<string> RegexSpecialCharacters = new List<string>
{
"\\",
".",
"+",
"*",
"?",
"[",
"^",
"]",
"$",
"(",
")",
"{",
"}",
"=",
"!",
"<",
">",
"|",
":",
"-"
};
foreach (var rgxSpecialChar in RegexSpecialCharacters)
rgxPattern = input.Replace(rgxSpecialChar, "\\" + rgxSpecialChar);
var regexSpecialCharacters = [
"\\", ".", "+", "*", "?",
"[", "^", "]", "$", "(",
")", "{", "}", "=", "!",
"<", ">", "|", ":", "-"
];
regexSpecialCharacters.forEach(rgxSpecChar =>
input = input.replace(new RegExp("\\" + rgxSpecChar,"gm"), "\\" +
rgxSpecChar))
在一个字符集合内,如果要匹配一个字面上的连字符-
,当它不位于开头或结尾时,需要进行转义。例如,在下面的模式中最后一个连字符的位置,需要进行转义:
[a-z0-9\-_]+
但在这里不需要转义:
[a-z0-9_-]+
a-z
匹配 a 和 z 之间的任何字符一样)。/
(尽管在字符集外部需要转义)。因此,以下语法是有效的;const pattern = /[/]/;
随着在JavaScript中引入Unicode正则表达式(即使用u
标志构造的正则表达式),这里的答案变得更加复杂。特别是:
非Unicode正则表达式支持“身份”转义;也就是说,如果一个字符在正则表达式模式中没有特殊的解释,那么对它进行转义不会产生任何效果。这意味着/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
问题:
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, '\\$&')
}
我在寻找与ESLint的“no-useless-escape”设置相关的列表,用于正则表达式。发现一些提到的字符在JS中不需要转义。这里另一个答案中更长的列表是针对PHP的,它确实需要转义其他字符。
在这个ESLint的github问题中,大约在中间位置,用户not-an-aardvark
解释了为什么该问题中引用的字符可能需要转义。
在javascript中,需要转义的字符是语法字符或以下字符之一:
^ $ \ . * + ? ( ) [ ] { } |
我链接到的github问题的回复包括有关“附录B”语义(我不太了解)的解释,允许取消转义上述提到的4个字符:) ] { }
。
另一个需要注意的是,转义不需要转义的字符不会造成任何伤害(除非你试图转义转义字符)。因此,我的个人经验法则是:“当你不确定时,请进行转义”
<input pattern="">
来说是这样的:https://dev59.com/oVoU5IYBdhLWcg3w559R - nrkn