JavaScript 字符转义序列
最近写了关于 HTML 中的字符引用和 CSS 中的转义序列的文章,我认为研究 JavaScript 字符转义也会很有趣。
字符代码、代码点和代码单元
代码点(也称为“字符代码”)是特定 Unicode 字符的数字表示。
例如版权符号©
的字符编码为169,十六进制可写为0xA9。
在 JavaScript 中,String#charCodeAt()
可用于获取不超过 U+FFFF 的任何字符的数字 Unicode 代码点(即代码点为 0xFFFF 的字符,十进制为 65535)。
由于 JavaScript 在内部使用 UCS-2 编码,较高的代码点由一对(较低值的)“代理”伪字符表示,这些伪字符用于构成真实字符。 要在 JavaScript 中获取这些更高代码点字符的实际字符代码,我们必须做一些额外的工作。 基本上,JavaScript 使用代码单元而不是代码点。
现在已经结束了,让我们来看看 JavaScript 字符串中不同类型的字符转义序列。
单字符转义序列
有一些保留的单字符转义序列用于字符串:
-
\b
: 退格键 (U+0008 BACKSPACE) -
\f
: 换页 (U+000C FORM FEED) -
\n
: 换行 (U+000A LINE FEED) -
\r
: 回车 (U+000D CARRIAGE RETURN) -
\t
: 水平制表符(U+0009 字符制表) -
\v
: 垂直制表符(U+000B 行制表) -
\0
: 空字符(U+0000 NULL)(仅当下一个字符不是十进制数字时;否则是八进制转义序列) -
\'
: 单引号 (U+0027 APOSTROPHE) -
\"
: 双引号 (U+0022 引号) -
\\
: 反斜杠 (U+005C REVERSE SOLIDUS)
使用以下正则表达式可以轻松记住所有单字符转义:\\[bfnrtv0'"\\]
。
请注意
,转义字符 \ 使特殊字符成为文字。
此规则只有一个例外:
'abc\
def' == 'abcdef'; // true
\
后跟一个新行不是字符转义序列,而是 LineContinuation
。 新行不会成为字符串的一部分。 这只是一种将字符串分布在多行上的方法(例如,为了更容易进行代码编辑),字符串实际上不包含任何换行符。 我想我们可以将 \
后跟一个新行视为空字符串的转义序列。
没有特殊含义的字符也可以转义(例如'\a' == 'a'
),但这当然不是必需的。 但是,规范不允许在 Unicode 转义序列之外使用 \u
,或在十六进制转义序列之外使用 \x
,这会导致某些引擎抛出语法错误。
注意
:IE < 9 将'\v'
视为'v'
而不是垂直制表符 ('\x0B'
)。 如果跨浏览器兼容性是一个问题,请使用\x0B
而不是 \v。
另一件需要注意的事情是 JSON 字符串中不允许使用 \v
和 \0
转义符。
八进制转义序列
字符代码低于 256 的任何字符(即扩展 ASCII 范围内的任何字符)都可以使用其八进制编码的字符代码进行转义,前缀为 \
。
请注意
,这与可以通过十六进制转义进行转义的字符范围相同。
使用相同的示例,版权符号 ('©'
) 的字符代码为 169,在八进制表示法中为 251,因此我们可以将其写为 '\251'
。
八进制转义可以由两个、三个或四个字符组成。 '\1'
, '\01'
和 '\001'
是等价的; 不需要零填充。 但是,如果八进制转义符(例如 '\1'
)是较大字符串的一部分,并且紧跟在 [0-7] 范围内的字符(例如 1),则下一个字符将被视为转义符的一部分 序列,直到最多匹配三个数字。 换句话说,'\12'
(相当于'\012'
的单个八进制字符转义符)与'\0012'
(八进制转义符'\001'
后跟未转义字符'2')不同。 通过简单的零填充八进制转义,我们可以避免这个问题。
请注意
,这里有一个例外:\0 本身不是八进制转义序列。 它看起来像一个,甚至等于 \00 和 \000,它们都是八进制转义序列——但除非它后面跟着一个十进制数字,否则它就像一个单字符转义序列。 或者,用规范的术语来说:EscapeSequence :: 0 [lookahead ∉ DecimalDigit]
。 使用以下正则表达式定义八进制转义语法可能是最简单的:\\(?:[1-7][0-7]{0,2}|[0-7]{2,3})
。
请注意八进制转义在 ES5 中已被弃用:
过去的 ECMAScript 版本包含了额外的语法和语义,用于指定八进制文字和八进制转义序列。 这些已从该版本的 ECMAScript 中删除。 这个非规范性附件为八进制文字和八进制转义序列提供了统一的语法和语义,以与一些旧的 ECMAScript 程序兼容。
此外,它们在严格模式下会产生语法错误:
当处理严格模式代码(见 10.1.1)时,符合规范的实现可能不会扩展 EscapeSequence 的语法以包含 B.1.2 中描述的 OctalEscapeSequence。
它们在模板文字中也是不允许的。
不要使用八进制转义; 改用十六进制转义。
十六进制转义序列
字符代码低于 256 的任何字符(即扩展 ASCII 范围内的任何字符)都可以使用其十六进制编码的字符代码进行转义,前缀为 \x
。 (请注意,这与可以通过八进制转义符进行转义的字符范围相同。)
十六进制转义为四个字符长。 它们要求在 \x
之后正好有两个字符。 如果十六进制字符代码只有一个字符长(所有小于 16 或十六进制的 10 的字符代码都是这种情况),您需要用前导 0 填充它。
例如,版权符号 '©'
的字符代码为 169,它以十六进制给出 A9,因此我们可以将其写为 **'\xA9'**。
此转义的十六进制部分不区分大小写; 换句话说,'\xa9' 和 '\xA9' 是等价的。
我们可以使用以下正则表达式定义十六进制转义语法:\\x[a-fA-F0-9]{2}
。
规范将这种转义序列称为“十六进制”有点令人困惑,因为 Unicode 转义也使用十六进制。
Unicode 转义序列
任何字符代码低于 65536 的字符都可以使用其字符代码的十六进制值进行转义,前缀为 \u
。 (如前所述,更高的字符代码由一对代理字符表示。)
Unicode 转义为六个字符长。 它们要求在 \u 之后恰好有四个字符。 如果十六进制字符代码只有一个、两个或三个字符长,则需要用前导零填充它。
版权符号 '©'
的字符代码为 169,以十六进制表示为 A9,因此我们可以将其写为 '\u00A9'。 同样,'♥' 可以写成 '\u2665'。
这种字符转义的十六进制部分不区分大小写; 换句话说,'\u00a9' 和 '\u00A9' 是等价的。
我们可以使用以下正则表达式定义 Unicode 转义语法:\u[a-fA-F0-9]{4}。
注意
:除了一些简单的转义之外,Unicode 转义是 JSON 规范唯一允许的转义。
ECMAScript 6:Unicode 代码点转义
ECMAScript 6 在字符串中引入了一种新的转义序列,即 Unicode 代码点转义。 此外,它将定义 String.fromCodePoint
和 String#codePointAt
,它们都接受代码点而不是类似 UCS-2/UTF-16
的代码单元。
实现后,任何字符都可以使用其字符代码的十六进制值进行转义,前缀为 \u{
,后缀为 }
。 这允许最大为 0x10FFFF 的代码点,这是 Unicode 定义的最高代码点。
Unicode 代码点转义至少包含五个字符。 \u{…} 中至少可以包含一个十六进制字符。 使用的十六进制数字的数量没有上限(例如 '\u{000000000061}' == 'a'
)但出于实际目的,我们不需要超过 6 个,除非执行不必要的零填充。
中心符号 (𝌆
) 的四边形代码点为 U+1D306,因此您可以将其写为 \u{1D306}
。 为了进行比较,如果我们要使用简单的 Unicode 转义符来表示此符号,则必须单独写出代理项的一半:'\uD834\uDF06'
。
这种字符转义的十六进制部分不区分大小写; 换句话说,'\u{1d306}'
和 '\u{1D306}'
是等价的。
我们可以使用以下正则表达式定义 Unicode 代码点转义语法:\\u\{([0-9a-fA-F]{1,})\}
。
控制转义序列
在正则表达式中(不是在字符串中!),任何字符代码大于 0 且小于 26 的字符都可以使用其脱字符符号字符进行转义,前缀为 \c
。
控制转义为三个字符长。 它们只需要跟在 \c
之后的一个字符。
例如,U+000A LINE FEED 在脱字符号中是 ^J
(因为 0x000A === 10
而 J 是字母表中的第 10 个字母)。 因此,匹配此符号的有效正则表达式将是 /\cJ/
,例如 /\cJ/.test('\n') == true
。
在这种字符转义中,\c
后面的脱字符不区分大小写; 换句话说,/\cJ/
和 /\cj/
是等价的。
以下是所有可用控制转义序列及其映射到的控制字符的列表:
转义序列 | Unicode 代码点 |
---|---|
\cA 或者 \ca | U+0001 START OF HEADING |
\cB 或者 \cb | U+0002 START OF TEXT |
\cC 或者 \cc | U+0003 END OF TEXT |
\cD 或者 \cd | U+0004 END OF TRANSMISSION |
\cE 或者 \ce | U+0005 ENQUIRY |
\cF 或者 \cf | U+0006 ACKNOWLEDGE |
\cG 或者 \cg | U+0007 BELL |
\cH 或者 \ch | U+0008 BACKSPACE |
\cI 或者 \ci | U+0009 CHARACTER TABULATION |
\cJ 或者 \cj | U+000A LINE FEED (LF) |
\cK 或者 \ck | U+000B LINE TABULATION |
\cL 或者 \cl | U+000C FORM FEED (FF) |
\cM 或者 \cm | U+000D CARRIAGE RETURN (CR) |
\cN 或者 \cn | U+000E SHIFT OUT |
\cO 或者 \co | U+000F SHIFT IN |
\cP 或者 \cp | U+0010 DATA LINK ESCAPE |
\cQ 或者 \cq | U+0011 DEVICE CONTROL ONE |
\cR 或者 \cr | U+0012 DEVICE CONTROL TWO |
\cS 或者 \cs | U+0013 DEVICE CONTROL THREE |
\cT 或者 \ct | U+0014 DEVICE CONTROL FOUR |
\cU 或者 \cu | U+0015 NEGATIVE ACKNOWLEDGE |
\cV 或者 \cv | U+0016 SYNCHRONOUS IDLE |
\cW 或者 \cw | U+0017 END OF TRANSMISSION BLOCK |
\cX 或者 \cx | U+0018 CANCEL |
\cY 或者 \cy | U+0019 END OF MEDIUM |
\cZ 或者 \cz | U+001A SUBSTITUTE |
我们可以使用以下正则表达式定义控制转义语法:\\c[a-zA-Z]
。
相关文章
使用 CSS 和 JavaScript 制作文本闪烁
发布时间:2023/04/28 浏览次数:146 分类:CSS
-
本文提供了使用 CSS、JavaScript 和 jQuery 使文本闪烁的详细说明。
在 PHP 变量中存储 Div Id 并将其传递给 JavaScript
发布时间:2023/03/29 浏览次数:69 分类:PHP
-
本文教导将 div id 存储在 PHP 变量中并将其传递给 JavaScript 代码。
在 JavaScript 中从字符串中获取第一个字符
发布时间:2023/03/24 浏览次数:93 分类:JavaScript
-
在本文中,我们将看到如何使用 JavaScript 中的内置方法获取字符串的第一个字符。
在 JavaScript 中获取字符串的最后一个字符
发布时间:2023/03/24 浏览次数:141 分类:JavaScript
-
本教程展示了在 javascript 中获取字符串最后一个字符的方法