ECMAScript正規表示式6個最新特性

Fundebug發表於2018-09-04

譯者按: 還沒學好ES6?ECMAScript 2018已經到來啦!

為了保證可讀性,本文采用意譯而非直譯。另外,本文版權歸原作者所有,翻譯僅用於學習。

1999年,ECMAScript 3新增了對正規表示式的支援。

16年之後,ECMAScript 6(即ECMAScript 2015或者ES6)引入了Unicode模式(u選項), sticky模式(y選項)以及RegExp.prototype.flags的getter方法

這篇部落格將介紹ECMAScript正規表示式的最新特性

1. dotAll模式(s選項)

這個特性已經在ECMAScript 2018正式釋出了。

預設情況下,.可以匹配任意字元,除了換行符:

/foo.bar/u.test('foo\nbar'); // false
複製程式碼

另外,.不能匹配Unicode字元,需要使用u選項啟用Unicode模式才行。

ES2018引入了dotAll模式,通過s選項可以啟用,這樣,.就可以匹配換行符了。

/foo.bar/su.test('foo\nbar'); // true
複製程式碼

2. Lookbehind斷言

這個特性已經在ECMAScript 2018正式釋出了。

ECMAScript目前僅支援lookahead斷言。

下面示例是Positive lookahead,匹配字串“42 dollars”中緊跟著是"dollars"的數字:

const pattern = /\d+(?= dollars)/u;
const result = pattern.exec('42 dollars');
console.log(result[0]); // 列印42
複製程式碼

下面示例是Negative lookahead,匹配字串“42 pesos”中緊跟著的不是"dollars"的數字:

const pattern = /\d+(?! dollars)/u;
const result = pattern.exec('42 pesos');
console.log(result[0]); // 列印42
複製程式碼

ES2018新增了lookbehind斷言

下面示例是Positive lookbehind,匹配字串“$42”中前面是"$"的數字:

const pattern = /(?<=\$)\d+/u;
const result = pattern.exec('$42');
console.log(result[0]); // 列印42
複製程式碼

下面示例是Negative lookbehind,匹配字串“$42”中前面不是是"$"的數字:

const pattern = /(?<!\$)\d+/u;
const result = pattern.exec('€42');
console.log(result[0]); // 列印42
複製程式碼

Fundebug專注於網頁、微信小程式、微信小遊戲,支付寶小程式,React Native,Node.js和Java線上BUG實時監控,歡迎免費試用

3. Named capture groups

這個特性已經在ECMAScript 2018正式釋出了。

目前,正規表示式中小括號匹配的分組是通過數字編號的:

const pattern = /(\d{4})-(\d{2})-(\d{2})/u;
const result = pattern.exec('2017-01-25');
console.log(result[0]); // 列印"2017-01-25"
console.log(result[1]); // 列印"2017"
console.log(result[2]); // 列印"01"
console.log(result[3]); // 列印"25"
複製程式碼

這樣很方便,但是可讀性很差,且不易維護。一旦正規表示式中小括號的順序有變化時,我們就需要更新對應的數字編號。

ES2018新增named capture groups, 可以指定小括號中匹配內容的名稱,這樣可以提高程式碼的可讀性,也便於維護。

const pattern = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/u;
const result = pattern.exec('2017-01-25');
console.log(result.groups.year); // 列印"2017"
console.log(result.groups.month); // 列印"01"
console.log(result.groups.day); // 列印"25"
複製程式碼

4. Unicode property escapes

這個特性已經在ECMAScript 2018正式釋出了。

Unicode標準為每一個字元分配了多個屬性。比如,當你要匹配希臘語字元時,則可以搜尋Script_Extensions屬性為Greek的字元。

Unicode property escapes使得我們可以使用ECMAScript正規表示式直接匹配Unicode字元的屬性:

const regexGreekSymbol = /\p{Script_Extensions=Greek}/u;
console.log(regexGreekSymbol.test('π')); // 列印true
複製程式碼

5. String.prototype.matchAll

這個特性還處在Stage 3 Draft

g和y選項通常用於匹配一個字串,然後遍歷所有匹配的子串,包括小括號匹配的分組。String.prototype.matchAll讓這個操作變得更加簡單了。

const string = 'Magic hex numbers: DEADBEEF CAFE 8BADF00D';
const regex = /\b[0-9a-fA-F]+\b/g;
for (const match of string.matchAll(regex)) {
	console.log(match);
}
複製程式碼

每一個迭代所返回的match物件與regex.exec(string)所返回的結果相同:

// Iteration 1:
[
	'DEADBEEF',
	index: 19,
	input: 'Magic hex numbers: DEADBEEF CAFE 8BADF00D'
]

// Iteration 2:
[
	'CAFE',
	index: 28,
	input: 'Magic hex numbers: DEADBEEF CAFE 8BADF00D'
]

// Iteration 3:
[
	'8BADF00D',
	index: 33,
	input: 'Magic hex numbers: DEADBEEF CAFE 8BADF00D'
]
複製程式碼

注意,這個特性還處在Stage 3 Draft,因此還存在變化的可能性,示例程式碼是根據最新的提案寫的。另外,瀏覽器也還沒有支援這個特性。String.prototype.matchAll最快可以被加入到ECMAScript 2019中。

6. 規範RegExp遺留特性

這個提案還處在Stage 3 Draft

這個提案規範了RegExp的遺留特性,比如RegExp.prototype.compile方法以及它的靜態屬性從RegExp.$1RegExp.$9。雖然這些特性已經棄用(deprecated)了,但是為了相容性我們不能將他們去。因此,規範這些RegExp遺留特性是最好的方法。因此,這個提案有助於保證相容性。

參考

關於Fundebug

Fundebug專注於JavaScript、微信小程式、微信小遊戲、支付寶小程式、React Native、Node.js和Java實時BUG監控。 自從2016年雙十一正式上線,Fundebug累計處理了6億+錯誤事件,得到了Google、360、金山軟體等眾多知名使用者的認可。歡迎免費試用!

ECMAScript正規表示式6個最新特性

版權宣告

轉載時請註明作者Fundebug以及本文地址:

blog.fundebug.com/2018/08/30/…