RegExp
Baseline 廣泛可用 *
RegExp 物件用於將文字與模式進行匹配。
有關正則表示式的介紹,請閱讀 JavaScript 指南中的正則表示式一章。有關正則表示式語法的詳細資訊,請閱讀正則表示式參考。
描述
字面量語法和建構函式
建立 RegExp 物件有兩種方式:字面量語法和建構函式。
以下三個表示式建立相同的正則表示式物件:
const re = /ab+c/i; // literal notation
// OR
const re = new RegExp("ab+c", "i"); // constructor with string pattern as first argument
// OR
const re = new RegExp(/ab+c/, "i"); // constructor with regular expression literal as first argument
正則表示式在使用之前必須經過編譯。這個過程可以提高它們的匹配效率。有關此過程的更多資訊可以在 dotnet 文件中找到。
字面量語法在表示式求值時編譯正則表示式。另一方面,RegExp 物件的建構函式 new RegExp('ab+c') 會在執行時編譯正則表示式。
當你希望從動態輸入構建正則表示式時,可以使用字串作為 RegExp() 建構函式的第一個引數。
建構函式中的標誌
表示式 new RegExp(/ab+c/, flags) 將使用第一個引數的源和第二個引數提供的標誌建立一個新的 RegExp。
使用建構函式時,需要遵循正常的字串轉義規則(在字串中包含特殊字元時,在特殊字元前加上 \)。
例如,以下是等效的
const re = /\w+/;
// OR
const re = new RegExp("\\w+");
正則表示式的特殊處理
注意: 判斷一個東西是否是“正則表示式”可以透過鴨子型別來完成。它不必是 RegExp!
一些內建方法會特殊處理正則表示式。它們透過多個步驟來判斷 x 是否是正則表示式:
x必須是一個物件(而不是原始值)。- 如果
x[Symbol.match]不是undefined,則檢查它是否為真值。 - 否則,如果
x[Symbol.match]是undefined,則檢查x是否是用RegExp建構函式建立的。(這一步很少發生,因為如果x是一個未被篡改的RegExp物件,它應該有一個Symbol.match屬性。)
請注意,在大多數情況下,它會透過 Symbol.match 檢查,這意味著:
- 一個真實的
RegExp物件的Symbol.match屬性的值是假值但不是undefined(即使其他一切都完好無損,如exec和[Symbol.replace]()),也可以像它不是正則表示式一樣使用。 - 一個沒有
RegExp物件的Symbol.match屬性將被視為正則表示式。
做出這個選擇是因為 [Symbol.match]() 是最能指示某個東西是否打算用於匹配的屬性。(exec 也可以使用,但因為它不是一個 Symbol 屬性,會導致太多的誤報。)特殊處理正則表示式的地方包括:
String.prototype.endsWith()、startsWith()和includes()如果第一個引數是正則表示式,則會丟擲TypeError。String.prototype.matchAll()和replaceAll()會檢查第一個引數是否為正則表示式,如果是,則在呼叫其[Symbol.matchAll]()或[Symbol.replace]()方法之前,檢查 global 標誌是否已設定。RegExp()建構函式只有當pattern是正則表示式(以及其他一些條件)時,才會直接返回pattern引數。如果pattern是正則表示式,它還會詢問pattern的source和flags屬性,而不是將pattern強制轉換為字串。
例如,String.prototype.endsWith() 會將所有輸入強制轉換為字串,但如果引數是正則表示式,它會丟擲錯誤,因為它只設計用於匹配字串,而使用正則表示式很可能是開發人員的錯誤。
"foobar".endsWith({ toString: () => "bar" }); // true
"foobar".endsWith(/bar/); // TypeError: First argument to String.prototype.endsWith must not be a regular expression
你可以透過將 [Symbol.match] 設定為非 undefined 的假值來繞過此檢查。這意味著該正則表示式不能用於 String.prototype.match()(因為沒有 [Symbol.match],match() 將使用 re.toString() 新增的兩個斜槓來構造新的 RegExp 物件),但它幾乎可以用於其他所有用途。
const re = /bar/g;
re[Symbol.match] = false;
"/bar/g".endsWith(re); // true
re.exec("bar"); // [ 'bar', index: 0, input: 'bar', groups: undefined ]
"bar & bar".replace(re, "foo"); // 'foo & foo'
類 Perl 的 RegExp 屬性
請注意,RegExp 的許多屬性都有長名稱和短名稱(類 Perl)。這兩個名稱總是指同一個值。(Perl 是 JavaScript 模仿其正則表示式的程式語言。)另請參閱已棄用的 RegExp 屬性。
建構函式
RegExp()-
建立新的
RegExp物件。
靜態屬性
RegExp.$1, …,RegExp.$9已棄用-
包含帶括號子字串匹配的靜態只讀屬性。
RegExp.input($_) 已棄用-
一個靜態屬性,包含正則表示式成功匹配的最後一個字串。
RegExp.lastMatch($&) 已棄用-
一個靜態只讀屬性,包含最後匹配的子字串。
RegExp.lastParen($+) 已棄用-
一個靜態只讀屬性,包含最後一個帶括號的子字串匹配。
RegExp.leftContext($`) 已棄用-
一個靜態只讀屬性,包含最近匹配之前的子字串。
RegExp.rightContext($') 已棄用-
一個靜態只讀屬性,包含最近匹配之後的子字串。
RegExp[Symbol.species]-
用於建立派生物件的建構函式。
靜態方法
RegExp.escape()-
轉義字串中任何潛在的正則表示式語法字元,並返回一個新字串,該字串可以安全地用作
RegExp()建構函式的字面量模式。
例項屬性
這些屬性定義在 RegExp.prototype 上,並由所有 RegExp 例項共享。
RegExp.prototype.constructor-
建立例項物件的建構函式。對於
RegExp例項,初始值為RegExp建構函式。 RegExp.prototype.dotAll-
.是否匹配換行符。 RegExp.prototype.flags-
包含
RegExp物件的標誌的字串。 RegExp.prototype.global-
是針對字串中的所有可能匹配測試正則表示式,還是隻針對第一個匹配。
RegExp.prototype.hasIndices-
正則表示式結果是否暴露捕獲子字串的起始和結束索引。
RegExp.prototype.ignoreCase-
在字串中嘗試匹配時是否忽略大小寫。
RegExp.prototype.multiline-
是否跨多行搜尋字串。
RegExp.prototype.source-
模式的文字。
RegExp.prototype.sticky-
搜尋是否具有粘性。
RegExp.prototype.unicode-
是否啟用 Unicode 功能。
RegExp.prototype.unicodeSets-
是否啟用
v標誌,它是u模式的升級。
這些屬性是每個 RegExp 例項的自有屬性。
lastIndex-
下一個匹配開始的索引。
例項方法
RegExp.prototype.compile()已棄用-
在指令碼執行期間(重新)編譯正則表示式。
RegExp.prototype.exec()-
在其字串引數中執行搜尋匹配。
RegExp.prototype.test()-
在其字串引數中測試匹配。
RegExp.prototype.toString()-
返回表示指定物件的字串。覆蓋
Object.prototype.toString()方法。 RegExp.prototype[Symbol.match]()-
對給定字串執行匹配並返回匹配結果。
RegExp.prototype[Symbol.matchAll]()-
返回正則表示式對字串的所有匹配項。
RegExp.prototype[Symbol.replace]()-
用新子字串替換給定字串中的匹配項。
RegExp.prototype[Symbol.search]()-
在給定字串中搜索匹配項並返回模式在字串中找到的索引。
RegExp.prototype[Symbol.split]()-
透過將字串拆分為子字串,將給定字串拆分為陣列。
示例
使用正則表示式更改資料格式
以下指令碼使用 String.prototype.replace() 方法匹配 first last 格式的名稱,並將其輸出為 last, first 格式。
在替換文字中,指令碼使用 $1 和 $2 來指示正則表示式模式中相應匹配括號的結果。
const re = /(\w+)\s(\w+)/;
const str = "Maria Cruz";
const newStr = str.replace(re, "$2, $1");
console.log(newStr);
這將顯示 "Cruz, Maria"。
使用正則表示式拆分具有不同行尾/行尾/換行的行
預設的行尾因平臺(Unix、Windows 等)而異。此示例中提供的行拆分適用於所有平臺。
const text = "Some text\nAnd some more\r\nAnd yet\nThis is the end";
const lines = text.split(/\r?\n/);
console.log(lines); // [ 'Some text', 'And some more', 'And yet', 'This is the end' ]
請注意,正則表示式中模式的順序很重要。
在多行上使用正則表示式
預設情況下,. 字元不匹配換行符。要使其匹配換行符,請使用 s 標誌(dotAll 模式)。
const s = "Please yes\nmake my day!";
s.match(/yes.*day/);
// Returns null
s.match(/yes.*day/s);
// Returns ["yes\nmake my day"]
使用帶粘性標誌的正則表示式
sticky 標誌表示正則表示式透過嘗試從 RegExp.prototype.lastIndex 開始匹配來在目標字串中執行粘性匹配。
const str = "#foo#";
const regex = /foo/y;
regex.lastIndex = 1;
regex.test(str); // true
regex.lastIndex = 5;
regex.test(str); // false (lastIndex is taken into account with sticky flag)
regex.lastIndex; // 0 (reset after match failure)
粘性標誌和全域性標誌之間的區別
使用粘性標誌 y 時,下一個匹配必須發生在 lastIndex 位置,而使用全域性標誌 g 時,匹配可以發生在 lastIndex 位置或之後。
const re = /\d/y;
let r;
while ((r = re.exec("123 456"))) {
console.log(r, "AND re.lastIndex", re.lastIndex);
}
// [ '1', index: 0, input: '123 456', groups: undefined ] AND re.lastIndex 1
// [ '2', index: 1, input: '123 456', groups: undefined ] AND re.lastIndex 2
// [ '3', index: 2, input: '123 456', groups: undefined ] AND re.lastIndex 3
// … and no more match.
使用全域性標誌 g 時,將匹配所有 6 位數字,而不僅僅是 3 位。
正則表示式和 Unicode 字元
\w 和 \W 只匹配基於 ASCII 的字元;例如,a 到 z、A 到 Z、0 到 9 和 _。
要匹配其他語言(如西里爾語或希伯來語)的字元,請使用 \uHHHH,其中 HHHH 是字元的十六進位制 Unicode 值。
此示例演示如何從單詞中分離出 Unicode 字元。
const text = "Образец text на русском языке";
const regex = /[\u0400-\u04ff]+/g;
const match = regex.exec(text);
console.log(match[0]); // 'Образец'
console.log(regex.lastIndex); // 7
const match2 = regex.exec(text);
console.log(match2[0]); // 'на' (did not log 'text')
console.log(regex.lastIndex); // 15
// and so on
Unicode 屬性轉義功能提供了一種更簡單的方法來定位特定的 Unicode 範圍,允許使用 \p{scx=Cyrl}(匹配任何西裡爾字母)或 \p{L}/u(匹配任何語言的字母)等語句。
從 URL 提取子域名
const url = "http://xxx.domain.com";
console.log(/^https?:\/\/(.+?)\./.exec(url)[1]); // 'xxx'
注意: 相對於使用正則表示式解析 URL,通常使用瀏覽器內建的 URL 解析器(透過 URL API)更好。
從動態輸入構建正則表示式
const breakfasts = ["bacon", "eggs", "oatmeal", "toast", "cereal"];
const order = "Let me get some bacon and eggs, please";
order.match(new RegExp(`\\b(${breakfasts.join("|")})\\b`, "g"));
// Returns ['bacon', 'eggs']
規範
| 規範 |
|---|
| ECMAScript® 2026 語言規範 # sec-regexp-regular-expression-objects |
瀏覽器相容性
載入中…
Firefox 特有注意事項
從 Firefox 34 開始,在捕獲組帶有量詞且阻止其執行的情況下,捕獲組的匹配文字現在是 undefined 而不是空字串。
// Firefox 33 or older
"x".replace(/x(.)?/g, (m, group) => {
console.log(`group: ${JSON.stringify(group)}`);
});
// group: ""
// Firefox 34 or newer
"x".replace(/x(.)?/g, (m, group) => {
console.log(`group: ${group}`);
});
// group: undefined
請注意,由於 Web 相容性,RegExp.$N 仍將返回空字串而不是 undefined (bug 1053944)。