ES2018 新特性
- 非同步迭代器
- 正規表示式反向(lookbehind)斷言
- 正規表示式 Unicode 轉義
- 非轉義序列的模板字串
- 正規表示式 s/dotAll 模式(本文)
- 正規表示式命名捕獲組
- 物件展開運算子
- Promise.prototype.finally
“正規表示式的 s
(dotAll) flag” 提案 proposal-regexp-dotall-flag 由 Mathias Bynens 負責,目前已經進入 stage 4,並將成為 ES9(ES2018) 的一部分。
1. 概述
在 JavaScript 正規表示式中 .
用來匹配任何單個字元。但是有 2 個例外:
1.1 多位元組 emoji 字元
let regex = /^.$/;
regex.test('?'); // false
複製程式碼
我們可以通過設定 u
標誌來解決,u
的含義是 unicode:
let regex = /^.$/u;
regex.test('?'); // true
複製程式碼
1.2 行終結符(line terminator characters)
行終結符包含:
- U+000A LINE FEED (LF) (
\n
) - 換行 - U+000D CARRIAGE RETURN (CR) (
\r
) - 回車 - U+2028 LINE SEPARATOR - 行分隔符
- U+2029 PARAGRAPH SEPARATOR - 段分隔符
還有一些其它字元,也可以作為一行的開始:
- U+000B VERTICAL TAB (
\v
) - U+000C FORM FEED (
\f
) - U+0085 NEXT LINE
目前 JavaScript 正規表示式的 .
可以匹配其中的一部分:
let regex = /./;
regex.test('\n'); // false
regex.test('\r'); // false
regex.test('\u{2028}'); // false
regex.test('\u{2029}'); // false
regex.test('\v'); // true
regex.test('\f'); // true
regex.test('\u{0085}'); // true
複製程式碼
在正規表示式中,用於表示字串開頭和字串結尾的元字元是 ^
和 $
, 因此一個變通的方式是使用 ^
來匹配。
/foo.bar/.test('foo\nbar'); // false
/foo[^]bar/.test('foo\nbar'); // true
複製程式碼
或者使用 \s
來匹配空白字元:
/foo.bar/.test('foo\nbar'); // false
/foo[\s]bar/.test('foo\nbar'); // true
複製程式碼
2. 增加 s/dotAll 標誌
在最新的 ECMAScript 規範中,為 JavaScript 的正規表示式增加了一個新的標誌 s
用來表示 dotAll。以使 .
可以匹配任意字元。
/foo.bar/s.test('foo\nbar'); // true
複製程式碼
High-level API
const re = /foo.bar/s; // 等價於 const re = new RegExp('foo.bar', 's');
re.test('foo\nbar'); // true
re.dotAll; // true
re.flags; // "s"
複製程式碼
3. 命名由來
既然是為了實現 dotAll 功能,為什麼不命名為 d
或者 a
。因為在其它語言的正規表示式實現中,已經使用 s
標誌了:
- Java 使用
Pattern.DOTALL
- C# 和 VB 使用
RegexOptions.Singleline
- Python 同時支援
re.DOTALL
和re.S
在支援正規表示式使用 flag 的語言如 Perl、PHP 也使用 s
作為標誌。
s
的含義是 singleline 和 dotAll。
singleline(單行)對應的是 multiline(多行)。
m
標誌用於指定多行輸入字串應該被視為多個行。如果使用 m
標誌,^
和 $
匹配的開始或結束是字串中的每一行,而不是整個字串的開始或結束。
/^java/.test('just\njava\n'); // false
/^java/m.test('just\njava\n'); // true
複製程式碼
m
標誌隻影響^
和$
s
標誌隻影響.
目前在 JavaScript 正則表示中所有修飾符的含義:
- g → global
- i → ignoreCase
- m → multiline
- y → sticky
- u → unicode
- s → dotAll
4. 實現
-
V8 - Chrome 62
-
XS, shipping in Moddable as of the January 17, 2018 update
-
regexpu (transpiler) with the
{ dotAllFlag: true }
option enabled