Javascript 正则表达式字符范围 A-z 匹配插入符号 (“^”)

Javascript Regular Expressions Character Range A-z Matches Caret ("^")

本文关键字:符号 插入 字符 正则表达式 范围 A-z Javascript      更新时间:2023-09-26

在Chrome控制台上,我注意到了这个奇怪之处:

/[^A-z]/.test("^")
false
/[A-z]/.test("^")
true
"^".charCodeAt(0)
94
"A".charCodeAt(0)
65
"z".charCodeAt(0)
122
/[a-zA-Z]/.test("^")
false

插入符号在 65-122 范围内匹配是有道理的,因为它的字符代码是 94,但我没有意识到/[A-z]/不等同于/[a-zA-Z]/。

所以我想我的问题是,javascript 是否使用 ASCII 代码进行像 A-z 这样的远程匹配?这是这种行为的解释吗?

编辑:

经过进一步调查,这似乎是真的

String.fromCharCode(91)
"["
String.fromCharCode(92)
"'"
String.fromCharCode(93)
"]"
String.fromCharCode(94)
"^"
String.fromCharCode(95)
"_"
String.fromCharCode(96)
"`"
/[^A-z]/.test("^[''_`")
false

ECMAScript 15.10.2.15 处理正则表达式计算期间基于范围的字符集的生成。在构建从字符A到字符B的范围(即A-B):

  1. a 成为字符集 A 中的一个角色。
  2. b 是字符集 B 中的一个字符
  3. i 是字符 a 的代码单位值
  4. j 为字符 b 的代码单位值
  5. 如果我>j,则抛出语法错误异常。
  6. 返回包含编号为 i 到 j 的所有字符(包括 ij)的集合。

这里的短语"代码单位值"是一个 Unicode 术语。因此,范围A-z包括其 Unicode 代码单元值介于 Az 之间的所有字符(包括 和 )。此范围(0x41 - 0x7A)包含六个非字母字符:

U+005B  [   5b  LEFT SQUARE BRACKET
U+005C  '   5c  REVERSE SOLIDUS
U+005D  ]   5d  RIGHT SQUARE BRACKET
U+005E  ^   5e  CIRCUMFLEX ACCENT
U+005F  _   5f  LOW LINE
U+0060  `   60  GRAVE ACCENT

/[A-z]/范围表示代码范围从 65 到 122,这也包括 94,这是^

这就是/[A-z]/匹配^[]_等的原因。

请注意,在正则表达式中,插入符号表示新行的开头。如果您指的是文字插入符号字符,则必须使用反斜杠对其进行转义。

但是,anubhava上面的答案是您看到这种行为的原因。