原生JS:RegExp對象詳解


RegExp對象

本文參考MDN做的詳細整理,方便大家參考[MDN](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript)

RegExp 構造函數可創建一個正則表達式對象,用特定的模式匹配文本。

語法


  
  
  
          
  1. RegExp(pattern [, flags])
  2. /pattern/flags

參數

  • pattern 正則表達式文本
flags修飾符 該參數可以是下面幾個值的任意組合:
  • g  全局匹配
  • i  忽略大小寫
  • m  讓開始和結束字符(^ 和 $)工作在多行模式(也就是,^ 和 $ 可以匹配字符串中每一行的開始和結束(行是由 \n 或 \r 分割的),而不只是整個輸入字符串的最開始和最末尾處。
  • u  Unicode。將模式視為Unicode碼位(code points)序列。
  • y   新增,大部分瀏覽器暫不支持,sticky;matches only from the index indicated by the lastIndex property of this regular expression in the target string (and does not attempt to match from any later indexes). This allows the match-only-at-start capabilities of the character "^" to effectively be used at any location in a string by changing the value of the lastIndex property.

有兩種方法可以創建一個正則對象:字面量和構造函數。要表示字符串,字面量形式不使用引號,而傳遞給構造函數的參數使用引號。下面表達式創建相同的正則表達式:


    
    
    
            
  1. /ab+c/i;
  2. new RegExp('ab+c', 'i'); //需要常規的字符轉義規則
  3. new RegExp(/ab+c/, 'i'); //ES6新增允許的寫法

  • 當表達式被賦值時,字面量形式提供正則表達式的編譯(compilation)狀態,正則對象在代碼載入時(即編譯時)生成,當正則表達式保持為常量時使用字面量。例如當你在循環中使用字面量構造一個正則表達式時,正則表達式不會在每一次迭代中都被重新編譯(recompiled)。
  • 而正則表達式對象的構造函數,如 new RegExp('ab+c') 提供了正則表達式運行時編譯(正則對象在代碼運行時生成)。如果你知道正則表達式模式將會改變,或者你事先不知道什么模式,而是從另一個來源獲取,如用戶輸入,這些情況都可以使用構造函數。
注意:不要把正則表達式字面量(或者正則表達式構造器)直接放在  while  條件表達式里(而應該先保存到一個變量)。因為 循環的每次匹配條件都是一個新的正則表達式, 每次迭代時  lastIndex  的屬性都被重置為0,如果匹配,將會造成一個死循環。

       
       
       
               
  1. var myRe = /ab*/g;
  2. var str = 'abbcdefabh';
  3. var myArray;
  4. while ((myArray = myRe.exec(str)) !== null) {
  5. var msg = 'Found ' + myArray[0] + '. ';
  6. msg += 'Next match starts at ' + myRe.lastIndex;
  7. console.log(msg);
  8. }

正則對象生成以后,有兩種使用方式:

  • 正則對象的方法:將字符串作為參數,如 regex.test(str)
  • 字符串對象的方法:正則對象被作為參數,如 str.match(regex)

正則表達式中的特殊字符

字符類別(Character Classes)

字符

含義

.

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

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

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

\d

匹配基本拉丁字母表(basic Latin alphabet)中的一個數字字符。等價於[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"。

  1. ^等價於: [\t\n\v\f\r \u00a0\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u2028\u2029\u3000]
  2. ^等價於: [^\t\n\v\f\r \u00a0\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u2028\u2029\u3000]


屬性

RegExp.prototype.lastIndex

是正則表達式的一個可讀可寫的整型屬性,用來指定下一次匹配的起始索引。

只有正則表達式使用了表示全局檢索的 "g" 標志時,該屬性才會起作用。此時應用下面的規則:

  • 如果 lastIndex 大於字符串的長度,則 regexp.test 和 regexp.exec 將會匹配失敗,然后 lastIndex 被設置為 0。
  • 如果 lastIndex 等於字符串的長度,且該正則表達式匹配空字符串,則該正則表達式匹配從 lastIndex 開始的字符串。(then the regular expression matches input starting at lastIndex.)
  • 如果 lastIndex 等於字符串的長度,且該正則表達式不匹配空字符串 ,則該正則表達式不匹配字符串,lastIndex 被設置為 0.。
  • 否則,lastIndex 被設置為緊隨最近一次成功匹配的下一個位置。

RegExp.prototype.source

返回一個當前正則表達式對象的模式文本的字符串,該字符串不會包含正則字面量兩邊的斜杠以及任何的標志字符。

RegExp.prototype.global

是否開啟全局匹配,global 的值是布爾對象,如果使用了 "g" 標志,則返回 true也就是匹配目標字符串中所有可能的匹配項,而不是只進行第一次匹配。它表明了正則表達式是否使用了 "g" 標志,global 是一個正則表達式實例的只讀屬性

RegExp.prototype.ignoreCase

在匹配字符串時是否要忽略字符的大小寫。返回true或false,只讀屬性。表明了正則表達式是否使用了 "i" 標志

RegExp.prototype.multiline

是否開啟多行模式匹配。返回true或false,只讀屬性。表明了正則表達式是否使用了 "m" 標志。若使用 了"m","^" 和 "$" 將會從只匹配正則字符串的開頭或結尾,變為匹配字符串中任一行的開頭或結尾。

RegExp.prototype.sticky 大部分瀏覽器還不支持

是否開啟粘滯匹配。


實例方法:

RegExp.prototype.exec(str)

為指定的一段字符串str執行搜索匹配操作。它的返回值是一個數組或者 null

  • 如果你僅僅是為了知道是否匹配,可以使用 RegExp.test() 方法,或者 String.search() 方法
  • 如果成功匹配,exec 方法返回一個數組,並且更新正則表達式對象的屬性。返回的數組包括匹配的字符串作為第一個元素,緊接着一個元素對應一個成功匹配被捕獲的字符串的捕獲括號
  • 如果正則模式是一個空字符串,則exec方法會匹配成功,但返回的也是空字符串。

  • 整個數組的length屬性等於捕獲匹配的數量再加1。
  • 如果正則表達式加上g修飾符,則可以使用多次exec方法,下一次搜索的位置從上一次匹配成功結束的位置開始。與exec方法不同,此時str.match(re)方法會一次性返回所有匹配成功的結果,且設置正則表達式的lastIndex屬性,對match方法無效,匹配總是從字符串的第一個字符開始。

思考下面的例子:


     
     
     
             
  1. var re = /quick\s(brown).+?(jumps)/ig;
  2. var result = re.exec('The Quick Brown Fox Jumps Over The Lazy Dog');

下面的表格展示這個腳本的返回值:

對象

屬性/索引

描述

例子

result

[0]

匹配的全部字符串

Quick Brown Fox Jumps

[1], ...[n ]

括號中的分組捕獲

[1] = Brown

[2] = Jumps

index

匹配到的字符位於原始字符串的基於0的索引值

4

input

原始字符串

The Quick Brown Fox Jumps Over The Lazy Dog

re

lastIndex

下一次匹配開始的位置

25

ignoreCase

是否使用了'i'標記使正則匹配忽略大小寫

true

global

是否使用了'g'標記來進行全局的匹配.

true

multiline

是否使用了'm'標記使正則工作在多行模式(也就是,^ 和 $ 可以匹配字符串中每一行的開始和結束(行是由 \n 或 \r 分割的),而不只是整個輸入字符串的最開始和最末尾處。)

false

source

正則模式的字符串

quick\s(brown).+?(jumps)

RegExp.prototype.test(str)

測試當前正則是否能匹配目標字符串,返回 true 或 false(類似於 String.search),如果正則表達式帶有g修飾符,則每一次test方法都從上一次結束的位置開始向后匹配。如果正則模式是一個空字符串,則匹配所有字符串。

RegExp.prototype.toString()

返回一個字符串,其值為該正則對象的字面量形式。覆蓋了Object.prototype.toString() 方法。



免責聲明!

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



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