天天看點

JavaScript深入了解-正規表達式

正規表達式

正規表達式是用于比對字元串中字元組合的模式。在JavaScript中,正規表達式也是對象。這些模式被用于

RegExp

exec

text

方法,以及

String

中的

match

matchAll

replace

search

split

方法

建立表達式

字面量

使用兩個

/

直接建立正則表達,已斜杠表示開始和結束

當腳本加載後,正規表達式字面量就會被編譯。當正規表達式儲存不變時,使用此方法可獲得更好的性能。

RegExp

構造函數

var reg = new RegRxp('ab','g')
// 等價于   var reg = /ab/g
           

字面量建立斜杠結束後面參數和構造函數第二個參數表示修飾符。

上面兩種寫法是等加價的都建立了一個在正規表達式對象。差別在于,第一種再引擎編譯代碼時,就會建立正規表達式。第二種方法在運作時建立表達式,是以字面量效率更高。并且字面量比較便利直覺,基本上都會采用字面量定義正規表達式。

執行個體屬性

正則修飾符相關執行個體屬性(隻讀)

  • ignoreCase

    :傳回布爾值,表示是否設定了

    i

    修飾符
  • global

    :傳回布爾值,表示是否設定了

    g

    修飾符
  • multiline

    :傳回布爾值,表示是否設定了

    m

    修飾符
  • flags

    :傳回一個字元串,包含設定的所有修飾符

與修飾符無關實力屬性:

  • lastIndex

    :傳回一個證書,表示下一次開始搜尋的位置
  • source

    :傳回正規表達式的字元串形式,隻讀
var reg = /abc/gim
//修飾符相關屬性
reg.ignoreCase  //true
reg.global  //true
reg.multiline  //true
reg.flags   //gim
//修飾符無關屬性
reg.lastIndex //0
reg.source    //abc
           

執行個體方法

正則執行個體方法

test()

在字元串中測試是否比對,傳回值味

true

false

var reg = /av/g
var s = 'avbabc'
reg.test(s)  //true

reg.lastIndex = 2
reg.test(s) //false
           

當正規表達式帶有

g

修飾符時,每一次

test

方法都會從上一次結束的位置開始向後比對,可以使用

lastIndex

檢視目前位置

var reg = /av/g
var s = 'avbavabc'

reg.lastIndex //0
reg.test(s)		//true

reg.lastIndex	//2
reg.test(s)		//true

reg.lastIndex //5
reg.test(s)		//false
           

如果正規表達式是一個空字元串,則比對所有的字元串,都傳回

true

exec()

在字元串中執行查找比對的字元,傳回一個數組,未比對到傳回

null

exec

方法傳回數組包含兩個屬性:

  • input

    :整個原字元串
  • index

    :模式比對成功的開始位置索引
var reg = /av/g
var s = 'avbavabc'

reg.exec(s)   //["av", index: 0, input: "avbavabc", groups: undefined]
reg.exec(s)		//["av", index: 3, input: "avbavabc", groups: undefined]
reg.exec(s)		//null
           

同test一樣,當正規表達式帶有

g

修飾符時,每一次

exec

方法都會從上一次結束的位置開始向後比對,可以使用

lastIndex

檢視目前位置

當正規表達式包含

()

組比對時,傳回的數組包含多個比對資料,第一個是整個正則比對成功的結果,第二個為括号内的比對結果,如果有多個括号,第三個為第二個括号内的比對内容。依次類推。

var reg = /a(v)/g
var s = 'avbavabc'

reg.exec(s)		//[ 'av', 'v', index: 0, input: 'avbavabc', groups: undefined ]
reg.exec(s) 	//[ 'av', 'v', index: 3, input: 'avbavabc', groups: undefined ]
reg.exec(s)  	//null
           

多個

()

var reg = /a(v)(b)/g
var s = 'avbavabc'

reg.exec(s) // [ 'avb', 'v', 'b', index: 0, input: 'avbavabc', groups: undefined ]
reg.exec(s) //null
           

String執行個體方法

match()

在字元串中執行查找比對的字元,傳回一個數組,未比對到傳回

null

當正規表達式不帶有

g

修飾符是,傳回的數組帶有

index

iuput

屬性

var reg = /ac/
var s = 'acbacvabc'
var s1 = 'aabaavabc'

s.match(reg)  //[ 'ac', index: 0, input: 'acbacvabc', groups: undefined ]
s1.match(reg) //null
           

正規表達式帶有

g

修飾符時,該方法會一次性傳回所有比對成功的結果數組。不再帶有

index

input

屬性

var reg = /ac/g
var s = 'acbacvabc'

s.match(reg) //[ 'ac', 'ac' ]
           

注意:設定正規表達式的

lastindex

屬性對

match

方法無效,

match

方法總是從字元串第一個開始比對。

matchAll()

在字元串中執行查找所有比對的字元,傳回一個疊代器。注意 ,在使用

matchAll

時,正規表達式需要帶有

g

修飾符,否則會運作報錯。

var reg = /a/g
var s = 'acbacvabc'


arr = [...s.matchAll(reg)]
console.log(arr)
//輸出:
/**
[
  [ 'a', index: 0, input: 'acbacvabc', groups: undefined ],
  [ 'a', index: 3, input: 'acbacvabc', groups: undefined ],
  [ 'a', index: 6, input: 'acbacvabc', groups: undefined ]
]
**/
           

search()

在字元串中執行查找比對的字元,傳回第一個比對到字元的位置,未比對到傳回-1

var reg = /en/g
var reg1 = /yo/g
var s = 'yuwenbo'

s.search(reg) //3
s.search(reg1)	//-1
           

replace()

在字元串中執行查找比對的字元,并且使用替換字元串替換比對到的子字元串。兩個參數一個是正規表達式,一個是需要替換的内容。

如果正則沒有

g

修飾符,隻替換第一個比對成功的值。如果有

g

修飾符,則替換所有比對成功的值。

var s = 'i love you'
console.log(s.replace(/\s/, '❤'))  //i❤love you
console.log(s.replace(/\s/g, '❤')) //i❤love❤you
           

replace

第二個參數可以使用

$

符号,用來更加友善的制定所替換的内容

  • $&

    :比對的子字元串
  • `$``:比對結果前面的文本
  • $'

    :比對結果後面的文本
  • $n

    :比對成功的第n組内容,n是從1開始的自然數
  • $$

    :指代美元符号

    $

console.log('he llo'.replace(/(\w+)\s(\w+)/, '$2 $1')) //llo he
console.log('hello'.replace(/e/, '-$`-$&-$\'-')) //h-h-e-llo-llo
           

replace

的第二個參數也可以作為一個函數,将每一個正則比對内容替換為函數的傳回值

函數可以接受多個參數,第一個為比對到的内容,後面為組比對内容(可以有多個組比對),倒數第二個參數為比對内容再字元串中的位置,倒數第一個參數為原字元串。

console.log('hello'.replace(/e/, function (match, index, str) {
 console.log(match, index, str)
 return '❤'
}))

//e 1 hello
//h❤llo
           

split()

使用正規表達式或者一個固定字元串分割一個字元串,并将分割後的子字元串存儲到數組中

該方法可接受兩個參數,第一個參數為正規表達式,表示分割規則,第二個參數是傳回數組的最大成員數

str = 'ni hao ya.hei hei hei'
str.split(/ |\./, 5) //[ 'ni', 'hao', 'ya', 'hei', 'hei' ]
           

總結:

判斷字元串是否被比對到,使用

test

或者

search

方法

想獲得更多的資訊,使用

exec

或者,

match

方法,會比較慢。

修飾符(标志符)

修飾符表示附加規則,放在正則模式的最尾部。可以單個使用,也可以一起使用。

//單個修飾符
'abAbab'.match(/a/g)  //["a","a"] 

//多個修飾符一起使用 
'abAbab'.match(/a/gi)  //["a", "A", "a"]
           

g

修飾符

全局搜尋,預設情況下隻比對一次,就停止像下比對了,加上修飾符會一直向下搜尋

i

修飾符

預設情況下會區分比對字元串的大小寫情況

m

修飾符

多行搜尋,多行模式,會修改

^

$

的行為

預設情況下,

^

$

比對字元串的開始處和結尾處

加上

m

修飾符,

^

$

還會比對行首和行尾,即

^

$

會識别換行符

\n

例如:

  • /yewen$/m.test('hi yuwen\n')

    true

  • /yewen$/.test('hi yuwen\n')

    false

s

修飾符

允許

.

比對換行符

u

修飾符

使用

unicode

碼的模式進行比對

y

修飾符

執行 粘性搜尋比對從目标字元串的目前位置開始

特殊字元

\

字元

轉義字元

正規表達式中需要比對特殊字元本身,需要再前面家反斜杠

\

正規表達式中,需要反斜杠轉義的:

^

,

.

,

[

,

$

,

(

,

)

,

|

,

*

,

+

,

?

,

{

,

\

^

字元

比對開始位置

如果設定多行标志,那麼也比對換行符後的位置

例如:

/^A/

會比對

"Ant"

中的

A

,但是不會比對

"ntA"

中的

A

$

字元

比對結束位置

如果設定多行标志,那麼也比對換行符前的位置

例如:

/A$/

會比對

"ntA"

中的

A

,但是不會比對

"Ant"

中的

A

*

字元

比對一個表達式0次或多次

等價于

{0, }

例如:

/yueno*/

會比對

"yuenoooyuen"

中的

yuenooo

yuen

+

字元

比對一個表達式1次或多次

等價于

{1, }

例如:

/yueno+/

隻會比對

"yuenoooyuen"

中的

yuenooo

?

字元

比對一個表達式0次或1次

等價于

{0, 1}

  • 例如:

    /yueno?/

    隻會比對

    "yuenoooyuen"

    中的

    yueno

  • 注意:

    ?

    如果緊跟再任何量詞

    *

    +

    ?

    {}

    的後面,将會使量詞變得非貪婪(比對盡量少的字元)
  • 例如:

    /yueno??/

    隻會比對

    "yuenoooyuen"

    中的

    yuen

.

字元

預設比對出換行符之外的任何單個字元
  • 例如:

    /.y/

    隻會比對

    "yuenoooyuen"

    中的

    oy

  • 例如:

    /..y/

    隻會比對

    "yuenoooyuen"

    中的

    ooy

(x)

字元

捕獲括号

正規表達式中的括号表示分組比對,括号中的模式可以用比對分組的内容

分組比對可以使用

\n

正則替換中,可以使用

$1

,

$2

文法
  • 例如:

    /(wenbo)+/.test('wenbowenbo')

    true

    ,表示比對

    wenbo

    整體一次或多次
  • 例如:

    "wenbo,zhijian".replace(/(wenbo),(zhijian)/, '$2,$1')

  • 輸出:

    zhijian,wenbo

(?=x)

字元

比對

X

但是不記住比對項

非捕獲括号,使你能夠定義與正規表達式運算符一起使用的子表達式

使用非捕獲括号,能比對元素,但是不能在使用

\n

$n

方法

x(?=y)

字元

比對>

x

,僅僅當>

x

後面是>

y

> ,先行斷言
  • 例如:

    'wenbo'.match(/wen(?=bo)/)

  • 輸出:

    [ 'wen', index: 0, input: 'wenbo', groups: undefined ]

  • 例如:

    'wenyu'.match(/wen(?=bo)/)

  • 輸出:null

(?<=y)x

字元

比對>

x

,僅僅當>

x

前面是>

y

,> 後行斷言
  • 例如:

    'wenbo'.match(/(?<=wen)bo/)

  • 輸出:

    [ 'bo', index: 3, input: 'wenbo', groups: undefined ]

  • 例如:

    'yubo'.match(/(?<=wen)bo/)

  • 輸出:null

x(?!y)

字元

比對>

x

,僅僅當>

x

後面不是>

y

時,> 正向否定查找

(?<=y)x

字元

比對>

x

,僅僅當>

x

前面不是>

y

> ,反向否定查找

x|y

字元

比對>

x

或者>

y

可以連用
  • 例如:

    'wenyu'.match(/w|e|n/g)

  • 輸出:

    [ 'w', 'e', 'n' ]

{n}

字元

比對前面一個字元剛好出現>

n

次,>

n

> 是一個正整數
  • 例如:

    'hello'.match(/l{2}/g)

  • 輸出:

    [ 'll' ]

{n,}

字元

比對一個字元至少出現了>

n

次,>

n

> 是一個正整數

{n,m}

字元

比對前面的字元至少>

n

> 次最多>

m

> 次,>

n

> ,>

m

是> 為正整數>

[xyz]

字元

字元集合> 比對方括号中的任意字元,包括轉義字元,可以使用破折号(-)制定一個字元,> 例如:>

[a-zA-Z1-9]

>
  • 例如:

    'hello 123'.match(/[a-h1-2]/g)

  • 輸出:

    [ 'h', 'e', '1', '2' ]

[^xyz]

字元

反向字元集,> 比對任何沒有包含再方括号中的字元
  • 例如:

    'hello 123'.match(/[^a-h1-2]/g)

  • 輸出:

    [ 'l', 'l', 'o', '3' ]

[\b]

字元

比對一個倒退(U+0008),不是>

\b

,不要弄混了

\b

字元

比對一個詞的邊界

例如:

  • /\bworld/.test('hello world') // true

  • /\bworld/.test('hello-world') // true

  • /\bworld/.test('helloworld') // false

\B

字元

比對一個非單詞邊界

例如:

  • /\bworld/.test('hello world') // false

  • /\bworld/.test('hello-world') // false

  • /\bworld/.test('helloworld') // true

\cX

字元

當X是出于A到Z之間字元的時候,比對字元串中的一個控制符

\d

字元

比對一個數字,等價于>

[0-9]

\D

字元

比對一個數字,等價于>

[^0-9]

\D

字元

比對一個數字,等價于>

[^0-9]

\f

字元

比對一個換頁符(U+000C)

\n

字元

比對一個換行符(U+000A)

\r

字元

比對一個回車符

\s

字元

比對一個空白字元,包括空格,制表符,換頁符,和換行符

[\f\n\r\t\v\u00a0\u1680\u180e\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff]

\S

字元

比對一個非空白字元

\t

字元

比對一個水準制表符

\v

字元

比對一個垂直制表符

\w

字元

比對一個單字字元(字母,數字或者下劃線)> ,等價于>

[A-Za-z0-9_]

\w

字元

比對一個非單字字元> ,等價于>

[A-Za-z0-9_]

\W

字元

比對一個非單字字元

\n

字元

傳回最後的第n個字捕獲比對的子字元,> 捕獲的數目以左括号計算

\0

字元

比對NULL字元(U+0000)

\xhh

字元

比對一個兩位十六進制數表示的字元(\x00-\xFF)

\uhhhh

字元

比對一個四位十六進制數表示的UTF-16代碼單元

\u{hhhhh}

字元或

\u{hhhh}

(僅當設定了U标志時)比對一個十六進制時候表示的Unicode字元

繼續閱讀