ES6入門之正則的擴充套件

故事膠片發表於2019-04-23

ES6入門之正則的擴充套件

1. 正則的擴充套件

  1. 引數為字串, 那麼第二個參數列示正規表示式的修飾符,如下:
var regex = new RegExp('xyz', 'i')  
// 等價於
var regex = /xyz/i
複製程式碼
  1. 引數為一個正規表示式,這時返回一個原有正規表示式的拷貝。如下:
var regex = new RegExp(/xyz/i)
// 等價於
var regex = /xyz/i
複製程式碼
  1. Es6中改變了這種行文。如果RegExp建構函式第一個引數是正則物件,那第二個引數可以指定修飾符,並且返回的正規表示式會忽略原有正規表示式的修飾符,只使用新指定的修飾符。 如下:
new RegExp(/abc/ig, 'i').flags
// 原有的ig 被 i 覆蓋
複製程式碼

2. 字串的正則方法

字串物件共有4個方法,可以使用正規表示式: match()、 replace()、search() 和 split()。在Es6中 全部呼叫RegExp的例項方法,全部定義在RegExp物件上。如下:

String.prototype.match 呼叫 RegExp.prototype[Symbol.match]
String.prototype.replace 呼叫 RegExp.prototype[Symbol.replace]
String.prototype.search 呼叫 RegExp.prototype[Symbol.search]
String.prototype.split 呼叫 RegExp.prototype[Symbol.split
複製程式碼

3. u 修飾符

ES6 對正規表示式新增了 u 修飾符,用來正確處理大於\uFFFF的Unicode字元。如下:

/^\uD83D/u.test('\uD83D\uDC2A') // false
/^\uD83D/.test('\uD83D\uDC2A') // true
// 如上程式碼因為在ES5中 不支援四個位元組的 UTF-16編碼,會將為識別為兩個字元 導致 第二行為true
但是加了 u 修飾符後,ES6將為識別為一個字元,所以第一行為flase
複製程式碼

4. RegExp.prototype.unicode 屬性

正則例項物件新增 unicode 屬性,用來判斷表示是否設定了u修飾符,如下:

const r1 = /hello/;
const r2 = /hello/u;

r1.unicode // false
r2.unicode // true
複製程式碼

5. y 修飾符

和 g 修飾符相似,全域性匹配,但是下次匹配都是從上次匹配成功的下一個位置開始。而g 只要剩餘位置中存在匹配即可,y 必須從剩餘的第一個位置開始。如下:

var s = 'aaa_aa_a';
var r1 = /a+/g;
var r2 = /a+/y;

r1.exec(s) // ["aaa"]
r2.exec(s) // ["aaa"]

r1.exec(s) // ["aa"]
r2.exec(s) // null

// 第一次執行後 為 _aa_a g 只要剩餘位置存在即可匹配,返回 aa
// y 則是從上一次結果後的第一個位置開始,因為是_ 所以返回null
複製程式碼

6. RegExp.prototype.sticky 屬性

與y修飾符相匹配,ES6 的正則例項物件多了sticky屬性,表示是否設定了y修飾符 如下:

var r = /hello\d/y;
r.sticky // true
複製程式碼

7. RegExp.prototype.flags 屬性

ES6 為正規表示式新增了flags屬性,會返回正規表示式的修飾符。

// ES5 的 source 屬性
// 返回正規表示式的正文
/abc/ig.source
// "abc"

// ES6 的 flags 屬性
// 返回正規表示式的修飾符
/abc/ig.flags
// 'gi'
複製程式碼

8. s 修飾符:dotAll 模式

匹配的是任意單個字元,用來匹配任意單個字元,如下:

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

9. Unicode 屬性類

ES2018 引入了一種新的類的寫法\p{...}和\P{...},允許正規表示式匹配符合 Unicode 某種屬性的所有字元。

const regexGreekSymbol = /\p{Script=Greek}/u;
regexGreekSymbol.test('π') // true
複製程式碼

10. 具名組匹配

正常多個匹配 可能用圓括號包起,如下:

const RE_DATE = /(\d{4})-(\d{2})-(\d{2})/;

const matchObj = RE_DATE.exec('1999-12-31');
const year = matchObj[1]; // 1999
const month = matchObj[2]; // 12
const day = matchObj[3]; // 31
複製程式碼

但是以上的寫法不容易看懂,理解較為困難,而且只能用數字序號,另外如果陣列順序變了,還需要修改引用的序號。所以就有了具名組匹配。允許為每一個組匹配指定一個名字,既便於閱讀程式碼,又便於引用。即使組的順序變了,葉不用去更改匹配後的處理程式碼。如下:

const RE_DATE = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/;

const matchObj = RE_DATE.exec('1999-12-31');
const year = matchObj.groups.year; // 1999
const month = matchObj.groups.month; // 12
const day = matchObj.groups.day; // 31

// 格式: “具名組匹配”在圓括號內部,模式的頭部新增“問號 + 尖括號 + 組名”(?<year>)
複製程式碼

11. String.prototype.matchAll

如果一個正規表示式在一個字串中有多個匹配,現在使用的是 g 修飾符 或者 y 修飾符 迴圈 取出。現在有了新的提案。就是用 String.prototype.matchAll 一次性取出,但是它返回的不是一個陣列,而是一個遍歷器。然後可以用 for ... of 取出。

歡迎關注 公眾號【小夭同學】

歡迎關注 公眾號【小夭同學】

ES6入門系列

ES6入門之let、cont

ES6入門之變數的解構賦值

ES6入門之字串的擴充套件

Git教程

前端Git基礎教程

相關文章