RegExp in JavaScript
之前對正規表達式一直不太熟悉,也沒仔細去研究正則規則寫法是什麼種類,所以踩到支援性的雷。大多數正規式會支援正規表達式的原因是,它是一個對於文字操作非常強大的工具,本來要寫數十行複雜邏輯的判斷式,只要一行就能達成。
ES2018 新增的功能
正則表達式在 1999 年在 ECMAScript 標準第三版成為 JavaScript 的一部份,而在 ES2018 標準第九版時,新增了以下的功能,大幅改善對文字處理的能力。這邊文章要說明的是關於 assertions,大部分程式碼範例參考自此篇文章。
- Lookbehind assertions
- Named capture groups
- a(dot) Flag
- Unidocde property escapes
這些新功能的支援度目前還不高,尤其是 lookbehind 支援
Assertions
想要 match 文字是否符合規則,需要仰賴文字前後的順序,從而丟棄不合規則的 pattern。尤其是當我們處理到很長的字串,比對的過程中,幾乎都是不正確的格式。好險正則表達式基本上都有提供 lookbehind assertions
和 lookahead assertions
,讓我們的格式判斷能有效率。
Lookhead
在 ES2018 之前,JavaScript 有提供lookahead assertion
,分為 positive 和 negative。
Positive lookahead 用 (?=...)
const re = /Project(?= 10)/;
console.log(re.exec('Project')); // null
console.log(re.exec('Project5')); // null
console.log(re.exec('Project 5')); // null
console.log(re.exec('Project 10'));
// ["Project", index: 0, input: "Project 10", groups: undefined]
Negative lookahead 用 (?!...)
const re2 = /Lucky(?!Star)/;
console.log(re2.exec('LuckyStar'));
// null
console.log(re2.exec('LuckyGuy'));
// ["Lucky", index: 0, input: "LuckyGuy", groups: undefined]
console.log(re2.exec('LuckyOne'));
// ["Lucky", index: 0, input: "LuckyOne", groups: undefined]
console.log(re2.exec('Lucky'));
// ["Lucky", index: 0, input: "Lucky", groups: undefined]
Lookbehind
ES2018 ,JavaScript 新增了lookbehind assertions
作為 lookahead assertions
,一樣分為 positive 和 negative。
Positive lookbehind 用 (?<=...)
const re = /(?<=€)\d+(\.\d*)?/;
console.log(re.exec('199'));
// null
console.log(re.exec('$199'));
// null
console.log(re.exec('€199'));
// ["199", undefined, index: 1, input: "€199", groups: undefined]
Negative lookbehind 用 (?<!...)
const re = /(?<!\d{3}) meters/;
console.log(re.exec('10 meters'));
// [" meters", index: 2, input: "10 meters", groups: undefined]
console.log(re.exec('100 meters'));
// null
搭配一同使用
positive lookbehind
(?<=...)
和 negative lookbehind(?<!...)
const re = /(?<=\d{2})(?<!35) meters/;
console.log(re.exec('35 meters'));
// → null
console.log(re.exec('meters'));
// → null
console.log(re.exec('4 meters'));
// → null
console.log(re.exec('14 meters'));
// → ["meters", index: 2, input: "14 meters", groups: undefined]
- 數字要兩位數。
- 並且,數字不是 35。
- 符合以上兩個規則,
exec()
就會回傳找到的結果陣列。
留言