RegExp正則表達式——更深層次解析


轉自:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/RegExp

 

RegExp 構造函數創建了一個正則表達式對象,用於將文本與一個模式匹配。

有關正則表達式的介紹,請閱讀 JavaScript指南中的正則表達式章節

語法

字面量, 構造函數和工廠符號都是可以的:

/pattern/flags
new RegExp(pattern [, flags])
RegExp(pattern [, flags])

參數

pattern
正則表達式的文本。
flags

如果指定,標志可以具有以下值的任意組合:

g
全局匹配;找到所有匹配,而不是在第一個匹配后停止
i
忽略大小寫
m
多行; 將開始和結束字符(^和$)視為在多行上工作(也就是,分別匹配每一行的開始和結束(由 \n 或 \r 分割),而不只是只匹配整個輸入字符串的最開始和最末尾處。
u
Unicode; 將模式視為Unicode序列點的序列
y
粘性匹配; 僅匹配目標字符串中此正則表達式的lastIndex屬性指示的索引(並且不嘗試從任何后續的索引匹配)。

描述

有兩種方法來創建一個RegExp對象:一是字面量、二是構造函數。要指示字符串,字面量的參數不使用引號,而構造函數的參數使用引號。因此,以下表達式創建相同的正則表達式:

/ab+c/i; new RegExp('ab+c', 'i'); new RegExp(/ab+c/, 'i');

當表達式被賦值時,字面量形式提供正則表達式的編譯(compilation)狀態,當正則表達式保持為常量時使用字面量。例如當你在循環中使用字面量構造一個正則表達式時,正則表達式不會在每一次迭代中都被重新編譯(recompiled)。

而正則表達式對象的構造函數,如 new RegExp('ab+c') 提供了正則表達式運行時編譯(runtime compilation)。如果你知道正則表達式模式將會改變,或者你事先不知道什么模式,而是從另一個來源獲取,如用戶輸入,這些情況都可以使用構造函數。

從ECMAScript 6開始,當第一個參數為正則表達式而第二個標志參數存在時,new RegExp(/ab+c/, 'i')不再拋出TypeError (“當從其他正則表達式進行構造時不支持標志”)的異常,取而代之,將使用這些參數創建一個新的正則表達式。

當使用構造函數創造正則對象時,需要常規的字符轉義規則(在前面加反斜杠 \)。比如,以下是等價的:

var re = new RegExp("\\w+"); var re = /\w+/;

正則表達式中特殊字符的含義

字符類別(Character Classes)
字符 含義
.

(點號,小數點) 匹配任意單個字符,但是行結束符除外:\n \r \u2028 或 \u2029

在字符集中,點( . )失去其特殊含義,並匹配一個字面點( . )。

需要注意的是,m 多行(multiline)標志不會改變點號的表現。因此為了匹配多行中的字符集,可使用[^] (當然你不是打算用在舊版本 IE 中),它將會匹配任意字符,包括換行符。

例如,/.y/ 匹配 "yes make my day" 中的 "my" 和 "ay",但是不匹配 "yes"。

\d

匹配任意阿拉伯數字。等價於[0-9]

例如,/\d/ 或 /[0-9]/ 匹配 "B2 is the suite number." 中的 '2'。 

\D

匹配任意一個不是阿拉伯數字的字符。等價於[^0-9]

例如,/\D/ 或 /[^0-9]/ 匹配 "B2 is the suite number." 中的 'B'。

\w

匹配任意來自基本拉丁字母表中的字母數字字符,還包括下划線。等價於 [A-Za-z0-9_]

例如,/\w/ 匹配 "apple" 中的 'a',"$5.28" 中的 '5' 和 "3D" 中的 '3'。

\W

匹配任意不是基本拉丁字母表中單詞(字母數字下划線)字符的字符。等價於 [^A-Za-z0-9_]

例如,/\W/ 或 /[^A-Za-z0-9_]/ 匹配 "50%" 中的 '%'。

\s

匹配一個空白符,包括空格、制表符、換頁符、換行符和其他 Unicode 空格。

等價於 [ \f\n\r\t\v​\u00a0\u1680​\u180e\u2000​\u2001\u2002​\u2003\u2004​ \u2005\u2006​\u2007\u2008​\u2009\u200a​\u2028\u2029​​\u202f\u205f​ \u3000]。

例如 /\s\w*/ 匹配 "foo bar" 中的 ' bar'。

\S

匹配一個非空白符。等價於 [^ \f\n\r\t\v​\u00a0\u1680​\u180e\u2000​\u2001\u2002​\u2003\u2004​ \u2005\u2006​\u2007\u2008​\u2009\u200a​\u2028\u2029​\u202f\u205f​\u3000]

例如,/\S\w*/ 匹配 "foo bar" 中的 'foo'。

\t 匹配一個水平制表符(tab)
\r 匹配一個回車符(carriage return)
\n 匹配一個換行符(linefeed)
\v 匹配一個垂直制表符(vertical tab)
\f 匹配一個換頁符(form-feed)
[\b] 匹配一個退格符(backspace)(不要與 \b 混淆)
\0 匹配一個 NUL 字符。不要在此后面跟小數點。
\cX

X 是 A - Z 的一個字母。匹配字符串中的一個控制字符。

例如,/\cM/ 匹配字符串中的 control-M。

\xhh 匹配編碼為 hh (兩個十六進制數字)的字符。
\uhhhh 匹配 Unicode 值為 hhhh (四個十六進制數字)的字符。
\

對於那些通常被認為字面意義的字符來說,表示下一個字符具有特殊用處,並且不會被按照字面意義解釋。

例如 /b/ 匹配字符 'b'。在 b 前面加上一個反斜杠,即使用 /\b/,則該字符變得特殊,以為這匹配一個單詞邊界。

對於那些通常特殊對待的字符,表示下一個字符不具有特殊用途,會被按照字面意義解釋。

例如,* 是一個特殊字符,表示匹配某個字符 0 或多次,如 /a*/ 意味着 0 或多個 "a"。 為了匹配字面意義上的 * ,在它前面加上一個反斜杠,例如,/a\*/匹配 'a*'。

字符集合(Character Sets)
字符 含義
[xyz]

一個字符集合,也叫字符組。匹配集合中的任意一個字符。你可以使用連字符'-'指定一個范圍。

例如,[abcd] 等價於 [a-d],匹配"brisket"中的'b'和"chop"中的'c'。

[^xyz]

一個反義或補充字符集,也叫反義字符組。也就是說,它匹配任意不在括號內的字符。你也可以通過使用連字符 '-' 指定一個范圍內的字符。

例如,[^abc] 等價於 [^a-c]。 第一個匹配的是 "bacon" 中的'o' 和 "chop" 中的 'h'。

邊界(Boundaries)
字符 含義
^

匹配輸入開始。如果多行(multiline)標志被設為 true,該字符也會匹配一個斷行(line break)符后的開始處。

例如,/^A/ 不匹配 "an A" 中的 "A",但匹配 "An A" 中的 "A"。

$

匹配輸入結尾。如果多行(multiline)標志被設為 true,該字符也會匹配一個斷行(line break)符的前的結尾處。

例如,/t$/ 不匹配 "eater" 中的 "t",但匹配 "eat" 中的 "t"。

\b

匹配一個零寬單詞邊界(zero-width word boundary),如一個字母與一個空格之間。 (不要和 [\b] 混淆)

例如,/\bno/ 匹配 "at noon" 中的 "no",/ly\b/ 匹配 "possibly yesterday." 中的 "ly"。

\B

匹配一個零寬非單詞邊界(zero-width non-word boundary),如兩個字母之間或兩個空格之間。

例如,/\Bon/ 匹配 "at noon" 中的 "on",/ye\B/ 匹配 "possibly yesterday." 中的 "ye"。

分組(Grouping)與反向引用(back references)
字符 含義
(x)

匹配 x 並且捕獲匹配項。 這被稱為捕獲括號(capturing parentheses)。

例如,/(foo)/ 匹配且捕獲 "foo bar." 中的 "foo"。被匹配的子字符串可以在結果數組的元素 [1], ..., [n] 中找到,或在被定義的 RegExp 對象的屬性 $1, ..., $9 中找到。

捕獲組(Capturing groups)有性能懲罰。如果不需再次訪問被匹配的子字符串,最好使用非捕獲括號(non-capturing parentheses),見下面。

\n

n 是一個正整數。一個反向引用(back reference),指向正則表達式中第 n 個括號(從左開始數)中匹配的子字符串。

例如,/apple(,)\sorange\1/ 匹配 "apple, orange, cherry, peach." 中的 "apple,orange,"。一個更全面的例子在該表格下面。

(?:x) 匹配 x 不會捕獲匹配項。這被稱為非捕獲括號(non-capturing parentheses)。匹配項不能夠從結果數組的元素 [1], ..., [n] 或已被定義的 RegExp 對象的屬性 $1, ..., $9 再次訪問到。
數量詞(Quantifiers)
字符 含義
x*

匹配前面的模式 x 0 或多次。

例如,/bo*/ 匹配 "A ghost booooed" 中的 "boooo","A bird warbled" 中的 "b",但是不匹配 "A goat grunted"。

x+

匹配前面的模式 x 1 或多次。等價於 {1,}

例如,/a+/ 匹配 "candy" 中的 "a","caaaaaaandy" 中所有的 "a"。

x*?
x+?

像上面的 * 和 + 一樣匹配前面的模式 x,然而匹配是最小可能匹配。

例如,/".*?"/ 匹配 '"foo" "bar"' 中的 '"foo"',而 * 后面沒有 ? 時匹配 '"foo" "bar"'。

x?

匹配前面的模式 x 0 或 1 次。

例如,/e?le?/ 匹配 "angel" 中的 "el","angle" 中的 "le"。

如果在數量詞 *+? 或 {}, 任意一個后面緊跟該符號(?),會使數量詞變為非貪婪( non-greedy) ,即匹配次數最小化。反之,默認情況下,是貪婪的(greedy),即匹配次數最大化。

在使用於向前斷言(lookahead assertions)時,見該表格中 (?=)、(?!) 和 (?:) 的說明。

x(?=y) 只有當 x 后面緊跟着 y 時,才匹配 x。 例如,/Jack(?=Sprat)/ 只有在 'Jack' 后面緊跟着 'Sprat' 時,才會匹配它。/Jack(?=Sprat|Frost)/ 只有在 'Jack' 后面緊跟着 'Sprat' 或 'Frost' 時,才會匹配它。然而,'Sprat' 或 'Frost' 都不是匹配結果的一部分。
x(?!y)

只有當 x 后面不是緊跟着 y 時,才匹配 x。例如,/\d+(?!\.)/ 只有當一個數字后面沒有緊跟着一個小數點時,才會匹配該數字。

/\d+(?!\.)/.exec("3.141") 匹配 141 而不是 3.141。

x|y

匹配 x 或 y

例如,/green|red/ 匹配 "green apple" 中的 ‘green',"red apple." 中的 'red'。

x{n}

n 是一個正整數。前面的模式 x 連續出現 n 次時匹配。

例如,/a{2}/ 不匹配 "candy," 中的 "a",但是匹配 "caandy," 中的兩個 "a",且匹配 "caaandy." 中的前兩個 "a"。

x{n,}

n 是一個正整數。前面的模式 x 連續出現至少 n 次時匹配。

例如,/a{2,}/ 不匹配 "candy" 中的 "a",但是匹配 "caandy" 和 "caaaaaaandy." 中所有的 "a"。

x{n,m}

n 和 m 為正整數。前面的模式 x 連續出現至少 n 次,至多 m 次時匹配。

例如,/a{1,3}/ 不匹配 "cndy",匹配 "candy," 中的 "a","caandy," 中的兩個 "a",匹配 "caaaaaaandy" 中的前面三個 "a"。注意,當匹配 "caaaaaaandy" 時,即使原始字符串擁有更多的 "a",匹配項也是 "aaa"。

斷言(Assertions)
字符 含義
x(?=y)

僅匹配被y跟隨的x。

舉個例子,/Jack(?=Sprat)/,如果"Jack"后面跟着sprat,則匹配之。

/Jack(?=Sprat|Frost)/ ,如果"Jack"后面跟着"Sprat"或者"Frost",則匹配之。但是,"Sprat" 和"Frost" 都不會在匹配結果中出現。

x(?!y)

僅匹配不被y跟隨的x。

舉個例子,/\d+(?!\.)/ 只會匹配不被點(.)跟隨的數字。
/\d+(?!\.)/.exec('3.141') 匹配"141",而不是"3.141"

 

  1. ^等價於:

    [\t\n\v\f\r \u00a0\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u2028\u2029\u3000]

屬性

For properties available on RegExp instances, see Properties of RegExp instances.
 
RegExp.prototype
允許為所有正則對象添加屬性。
RegExp.length
RegExp.length 值為 2。
Properties inherited from  Function:

方法

For methods available on RegExp instances, see Methods of RegExp instances.
全局對象  RegExp 自身沒有方法, 不過它會繼承一些方法通過原型鏈
 
Methods inherited from  Function:

RegExp 實例

屬性

查看已廢棄的RegExp屬性

注意,RegExp 對象的幾個屬性既有完整的長屬性名,也有對應的類 Perl 的短屬性名。兩個屬性都有着同樣的值。JavaScript 的正則語法就是基於 Perl 的。

RegExp.prototype. constructor
創建該正則對象的構造函數。
RegExp.prototype.global
是否開啟全局匹配,也就是匹配目標字符串中所有可能的匹配項,而不是只進行第一次匹配。
RegExp.prototype.ignoreCase
在匹配字符串時是否要忽略字符的大小寫。
RegExp.prototype.lastIndex
下次匹配開始的字符串索引位置。
RegExp.prototype.multiline
是否開啟多行模式匹配(影響 ^ 和 $ 的行為)。
RegExp.prototype.source
正則對象的源模式文本。
RegExp.prototype.sticky 
是否開啟粘滯匹配。
Properties inherited from  Object:

方法

查看已廢棄的RegExp方法

RegExp.prototype.exec()
在目標字符串中執行一次正則匹配操作。
RegExp.prototype.test()
測試當前正則是否能匹配目標字符串。
RegExp.prototype.toSource() 
返回一個字符串,其值為該正則對象的字面量形式。覆蓋了 Object.prototype.toSource 方法.
RegExp.prototype.toString()
返回一個字符串,其值為該正則對象的字面量形式。覆蓋了 Object.prototype.toString() 方法。

例子

例子:使用正則改變數據結構

下例使用 replace 方法 (繼承自 String)去匹配姓名 first last 輸出新的格式 last, first。腳本中使用 $1 和 $2 指明括號里先前的匹配.

var re = /(\w+)\s(\w+)/; var str = "John Smith"; var newstr = str.replace(re, "$2, $1"); print(newstr);

顯示 "Smith, John".

例子:在多行中使用正則表達式

var s = "Please yes\nmake my day!"; s.match(/yes.*day/); // Returns null s.match(/yes[^]*day/); // Returns 'yes\nmake my day'

例子: 使用帶有 ”sticky“ 標志的正則表達式

該例展示了,如何在正則表達式上使用 sticky 標志,用來匹配多行輸入的單獨行。

var text = "First line\nsecond line"; var regex = /(\S+) line\n?/y; var match = regex.exec(text); print(match[1]); // prints "First" print(regex.lastIndex); // prints 11 var match2 = regex.exec(text); print(match2[1]); // prints "Second" print(regex.lastIndex); // prints "22" var match3 = regex.exec(text); print(match3 === null); // prints "true"

可以使用 try { … } catch { … } 來測試運行時(run-time)是否支持 sticky 標志。這種情況下,必須使用 eval(…) 表達式或 RegExp(regex-stringflags-string) 語法(這是由於 /regex/flags 表示法將會在編譯時刻被處理,因此在 catch 語句塊處理異常前就會拋出一個異常。例如:

var supports_sticky; try { RegExp('','y'); supports_sticky = true; } catch(e) { supports_sticky = false; } alert(supports_sticky); // alerts "false" in Firefox 2, "true" in Firefox 3+

例子:使用正則表達式和 Unicode 字符

正如上面表格提到的,\w 或 \W 只會匹配基本的 ASCII 字符;如 'a' 到 'z'、 'A' 到 'Z'、 0 到 9 及 '_'。為了匹配其他語言中的字符,如西里爾(Cyrillic)或 希伯來語(Hebrew),要使用 \uhhhh,"hhhh" 表示以十六進制表示的字符的 Unicode 值。下例展示了怎樣從一個單詞中分離出 Unicode 字符。

var text = "Образец text на русском языке"; var regex = /[\u0400-\u04FF]+/g; var match = regex.exec(text); print(match[1]); // prints "Образец" print(regex.lastIndex); // prints "7" var match2 = regex.exec(text); print(match2[1]); // prints "на" [did not print "text"] print(regex.lastIndex); // prints "15" // and so on

這里有一個外部資源,用來獲取 Unicode 中的不同區塊范圍:Regexp-unicode-block

例子:從 URL 中提取子域名

var url = "http://xxx.domain.com"; print(/[^.]+/.exec(url)[0].substr(7)); // prints "xxx"

規范

Specification Status Comment
ECMAScript 1st Edition. Implemented in JavaScript 1.1 Standard Initial definition.
ECMAScript 5.1 (ECMA-262)
RegExp
Standard  
ECMAScript 2015 (6th Edition, ECMA-262)
RegExp
Standard  

瀏覽器兼容性

We're converting our compatibility data into a machine-readable JSON format. This compatibility table still uses the old format, because we haven't yet converted the data it contains. Find out how you can help!

Feature Chrome Firefox (Gecko) Internet Explorer Opera Safari
Basic support (Yes) (Yes) (Yes) (Yes) (Yes)
Sticky flag ("y") ? 3.0 (1.9) ? ? ?

[1] Behind a flag.

[2] At least from version 41.

Gecko-特定的 注釋

Starting with Gecko 34 (Firefox 34 / Thunderbird 34 / SeaMonkey 2.31), in the case of a capturing group with quantifiers preventing its exercise, the matched text for a capturing group is now undefined instead of an empty string:

// Firefox 33 or older
'x'.replace(/x(.)?/g, function(m, group) {
  console.log("'group:" + group + "'");
}); // 'group:'

// Firefox 34 or newer
'x'.replace(/x(.)?/g, function(m, group) {
  console.log("'group:" + group + "'");
}); // 'group:undefined'

Note that due to web compatibility, RegExp.$N will still return an empty string instead of undefined (bug 1053944).


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM