RegExp

Baseline 廣泛可用 *

此特性已相當成熟,可在許多裝置和瀏覽器版本上使用。自 ⁨2015 年 7 月⁩以來,各瀏覽器均已提供此特性。

* 此特性的某些部分可能存在不同級別的支援。

RegExp 物件用於將文字與模式進行匹配。

有關正則表示式的介紹,請閱讀 JavaScript 指南中的正則表示式一章。有關正則表示式語法的詳細資訊,請閱讀正則表示式參考

描述

字面量語法和建構函式

建立 RegExp 物件有兩種方式:字面量語法建構函式

  • 字面量語法在兩個斜槓之間包含一個模式,後面跟著可選的標誌,位於第二個斜槓之後。
  • 建構函式將其第一個引數作為字串或 RegExp 物件,將其第二個引數作為可選的標誌字串。

以下三個表示式建立相同的正則表示式物件:

js
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

使用建構函式時,需要遵循正常的字串轉義規則(在字串中包含特殊字元時,在特殊字元前加上 \)。

例如,以下是等效的

js
const re = /\w+/;
// OR
const re = new RegExp("\\w+");

正則表示式的特殊處理

注意: 判斷一個東西是否是“正則表示式”可以透過鴨子型別來完成。它不必是 RegExp

一些內建方法會特殊處理正則表示式。它們透過多個步驟來判斷 x 是否是正則表示式:

  1. x 必須是一個物件(而不是原始值)。
  2. 如果 x[Symbol.match] 不是 undefined,則檢查它是否為真值
  3. 否則,如果 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() 會將所有輸入強制轉換為字串,但如果引數是正則表示式,它會丟擲錯誤,因為它只設計用於匹配字串,而使用正則表示式很可能是開發人員的錯誤。

js
"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 物件),但它幾乎可以用於其他所有用途。

js
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 來指示正則表示式模式中相應匹配括號的結果。

js
const re = /(\w+)\s(\w+)/;
const str = "Maria Cruz";
const newStr = str.replace(re, "$2, $1");
console.log(newStr);

這將顯示 "Cruz, Maria"

使用正則表示式拆分具有不同行尾/行尾/換行的行

預設的行尾因平臺(Unix、Windows 等)而異。此示例中提供的行拆分適用於所有平臺。

js
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 模式)。

js
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 開始匹配來在目標字串中執行粘性匹配。

js
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 位置或之後。

js
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 的字元;例如,azAZ09_

要匹配其他語言(如西里爾語或希伯來語)的字元,請使用 \uHHHH,其中 HHHH 是字元的十六進位制 Unicode 值。

此示例演示如何從單詞中分離出 Unicode 字元。

js
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 提取子域名

js
const url = "http://xxx.domain.com";
console.log(/^https?:\/\/(.+?)\./.exec(url)[1]); // 'xxx'

注意: 相對於使用正則表示式解析 URL,通常使用瀏覽器內建的 URL 解析器(透過 URL API)更好。

從動態輸入構建正則表示式

js
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 而不是空字串。

js
// 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)。

另見