本章将阐述由 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
译者:杜亨莉