正規表示式是一種模式,提供強大的方式來搜尋和取代文字。
在 JavaScript 中,它們可透過 RegExp 物件取得,並整合在字串的方法中。
正規表示式
正規表示式(也稱為「regexp」或「reg」)包含一個模式和選用的旗標。
有兩種語法可建立正規表示式物件。
「長」語法
regexp = new RegExp("pattern", "flags");
以及「短」語法,使用斜線 "/"
regexp = /pattern/; // no flags
regexp = /pattern/gmi; // with flags g,m and i (to be covered soon)
斜線 /.../
告訴 JavaScript 我們正在建立正規表示式。它們扮演與字串引號相同的角色。
在兩種情況下,regexp
都會成為內建 RegExp
類別的執行個體。
這兩種語法之間的主要差異在於,使用斜線 /.../
的模式不允許插入運算式(例如包含 ${...}
的字串範本字面值)。它們是完全靜態的。
當我們在編寫程式碼時知道正規表示式時,就會使用斜線分隔符號,而這也是最常見的情況。而當我們需要從動態產生的字串中「即時」建立正規表示式時,則較常使用 new RegExp
。例如
let tag = prompt("What tag do you want to find?", "h2");
let regexp = new RegExp(`<${tag}>`); // same as /<h2>/ if answered "h2" in the prompt above
旗標
正規表示式可能有影響搜尋的旗標。
JavaScript 中只有 6 個旗標
i
- 使用此旗標,搜尋會區分大小寫:
A
和a
沒有差別(請參閱以下範例)。 g
- 使用此旗標,搜尋會尋找所有符合的項目,而沒有此旗標,只會傳回第一個符合的項目。
m
- 多行模式(在章節 錨點 ^ $ 的多行模式,旗標「m」 中介紹)。
s
- 啟用「點全部」模式,允許點
.
符合換行字元\n
(在章節 字元類別 中介紹)。 u
- 啟用完整的 Unicode 支援。此旗標會啟用代理對的正確處理。在章節 Unicode:旗標「u」和類別 \p{...} 中有更詳細的說明。
y
- 「黏著」模式:在文字中的確切位置進行搜尋(在章節 黏著旗標「y」,在位置進行搜尋 中介紹)
從這裡開始,色彩配置如下
- 正規表示式 –
紅色
- 字串(我們搜尋的範圍)–
藍色
- 結果 –
綠色
搜尋:str.match
如前所述,正規表示式已整合到字串方法中。
方法 str.match(regexp)
會在字串 str
中找出所有符合 regexp
的項目。
它有 3 種工作模式
-
如果正規表示式有旗標
g
,它會傳回一個陣列,其中包含所有符合的項目let str = "We will, we will rock you"; alert( str.match(/we/gi) ); // We,we (an array of 2 substrings that match)
請注意,
We
和we
都會被找到,因為旗標i
使正規表示式不區分大小寫。 -
如果沒有此旗標,它只會傳回第一個符合的項目,形式為陣列,其中完整符合的項目在索引
0
中,而其他詳細資料則在屬性中let str = "We will, we will rock you"; let result = str.match(/we/i); // without flag g alert( result[0] ); // We (1st match) alert( result.length ); // 1 // Details: alert( result.index ); // 0 (position of the match) alert( result.input ); // We will, we will rock you (source string)
如果正規表示式的一部分包含在括弧中,陣列可能會包含
0
以外的其他索引。我們將在章節 擷取群組 中介紹這個部分。 -
最後,如果沒有符合的項目,就會傳回
null
(不論是否有旗標g
)。這是一個非常重要的細微差別。如果沒有匹配項,我們不會收到一個空陣列,而是收到
null
。忘記這一點可能會導致錯誤,例如let matches = "JavaScript".match(/HTML/); // = null if (!matches.length) { // Error: Cannot read property 'length' of null alert("Error in the line above"); }
如果我們希望結果始終是一個陣列,我們可以這樣寫
let matches = "JavaScript".match(/HTML/) || []; if (!matches.length) { alert("No matches"); // now it works }
替換:str.replace
方法 str.replace(regexp, replacement)
使用 replacement
替換字串 str
中使用 regexp
找到的匹配項(如果存在標記 g
,則替換所有匹配項;否則,只替換第一個匹配項)。
例如
// no flag g
alert( "We will, we will".replace(/we/i, "I") ); // I will, we will
// with flag g
alert( "We will, we will".replace(/we/ig, "I") ); // I will, I will
第二個參數是 replacement
字串。我們可以在其中使用特殊字元組合來插入匹配項的片段
符號 | 替換字串中的動作 |
---|---|
$& |
插入整個匹配項 |
$` |
插入匹配項之前的字串部分 |
$' |
插入匹配項之後的字串部分 |
$n |
如果 n 是 1-2 位數字,則插入第 n 個括號的內容,有關更多資訊,請參閱章節 擷取群組 |
$<name> |
插入具有給定 name 的括號的內容,有關更多資訊,請參閱章節 擷取群組 |
$$ |
插入字元 $ |
使用 $&
的範例
alert( "I love HTML".replace(/HTML/, "$& and JavaScript") ); // I love HTML and JavaScript
測試:regexp.test
方法 regexp.test(str)
尋找至少一個匹配項,如果找到,則傳回 true
,否則傳回 false
。
let str = "I love JavaScript";
let regexp = /LOVE/i;
alert( regexp.test(str) ); // true
在本章節稍後,我們將研究更多正規表示法,逐步示範更多範例,並認識其他方法。
有關這些方法的完整資訊,請參閱文章 RegExp 和字串的方法。
摘要
- 正規表示法包含一個模式和一些選用標記:
g
、i
、m
、u
、s
、y
。 - 沒有標記和特殊符號(我們稍後會研究),使用正規表示法的搜尋與子字串搜尋相同。
- 方法
str.match(regexp)
尋找匹配項:如果存在g
標記,則尋找所有匹配項;否則,只尋找第一個匹配項。 - 方法
str.replace(regexp, replacement)
使用replacement
替換使用regexp
找到的匹配項:如果存在g
標記,則替換所有匹配項;否則,只替換第一個匹配項。 - 方法
regexp.test(str)
如果至少有一個匹配項,則傳回true
;否則,傳回false
。
留言
<code>
標籤,若要插入多行,請將它們包裝在<pre>
標籤中,若要插入超過 10 行,請使用沙盒 (plnkr、jsbin、codepen…)