ES2018 新特徵之:正規表示式 dotAll 模式

justjavac發表於2018-03-06

ES2018 新特性


“正規表示式的 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.DOTALLre.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. 實現

相關文章