本章将阐述由 Mathias Bynens 提出的提案——用于正则表达式的 “s
(dotAll
)“ 标志。
概述
目前,正则表达式中的点(.
)无法匹配换行符:
> /^.$/.test('\n')
false
复制代码
本提案指定的正则表达式标志 /s
可以改变现状:
> /^.$/s.test('\n')
true
复制代码
正则表达式中的点(.
)的限制
正则表达式中的点(.
)有两个限制。
首先,它不能匹配星体(非 BMP)字符,例如 emoji:
> /^.$/.test('?')
false
复制代码
这个可以利用 /u
标志来解决:
> /^.$/u.test('?')
true
复制代码
第二,它不能匹配换行符:
> /^.$/.test('\n')
false
复制代码
这个目前只能通过用其他标志替换 .
来解决,例如 [^]
(”非空字符“)或者 [\s\S]
(”空格或非空格“)。
> /^[^]$/.test('\n')
true
> /^[\s\S]$/.test('\n')
true
复制代码
ECMAScript 中可被识别的换行符
ECMAScript 的 换行符 产生的影响:
- 点(
.
),在所有正则表达式中都没有/s
这个标志。 ^
和$
,当标志/m
(multiline
) 被使用的时候。
在 ECMAScript 中被认为是换行符的字符有:
- U+000A 换行(LF)(
\n
) - U+000D 回车(CR)(
\r
) - U+2028 行分隔符
- U+2029 段落分隔符
此外,还有一些类似于换行的字符在 ECMAScript 中不被认为是换行符:
- U+000B 垂直制表符 (
\v
) - U+000C 换页符 (
\f
) - U+0085 下一行
这三个字符不需要其他标志就可以被 .
匹配:
> /^...$/.test('\v\f\u{0085}')
true
复制代码
提案
该提案引进正则表达式标志 /s
(“singleline”的缩写),使得 .
可以匹配换行符:
> /^.$/s.test('\n')
true
复制代码
/s
的全名是 dotAll
,该属性表示是否使用了 s
标志:
> /./s.dotAll
true
> /./s.flags
's'
> new RegExp('.', 's').dotAll
true
> /./.dotAll
false
复制代码
dotAll
vs. multiline
dotAll
只影响.
。multiline
只影响^
和$
。
常见问题
为什么这个标志被命名为 /s
?
既然 dotAll
可以很好的描述标志的作用,那么为什么不用 /a
或者 /d
命名呢?因为 /s
这个名称在其他语言的正则表达式中已被广泛应用(包括 Perl、Python、Java、c#、…)。
原文:http://exploringjs.com/es2018-es2019/ch_regexp-dotall-flag.html
译者:杜亨莉