學(xué)習(xí)資料:
4. 選擇、分組、向后引用
分組通過(guò)對(duì)文本加一對(duì)()圓括號(hào)來(lái)幫助執(zhí)行某種操作:
- 在兩種或者更多的可選模式中選擇一個(gè)
- 創(chuàng)建子模式
- 捕獲一個(gè)分組以便之后進(jìn)行后向引用
- 對(duì)組合的模式使用某項(xiàng)操作,如量詞
- 使用非捕獲分組
- 原子分組
- 選擇操作

文本中含有the的thence,部分也會(huì)高亮
4.1 子模式
一般,提到正則表達(dá)式中的子模式subpattern,指的是分組中的一個(gè)或者多個(gè)分組。子模式就是模式中的模式
多數(shù)情況,子模式中的條件能得到匹配的的前提是前面的模式得到了匹配,但也有例外,例如:
- 子模式不依賴前面的模式:
上面的(the|The|THE),有3個(gè)子模式: the, The, THE
這種情況下,第2個(gè)子模式并不需要依賴于是否匹配第1個(gè),盡管 最左邊的模式會(huì)首先匹配
- 子模式依賴前面的模式:

整體含義:匹配到t或者T后,再匹配一個(gè)h,接下來(lái)是e或者eir
能夠匹配到的4個(gè)單詞: the, their, The, Their
第2個(gè)e|eir子模式,必須依賴于第1個(gè)t|T子模式
括號(hào)對(duì)于子模式不是必需的
- 字符組子模式:

兩個(gè)\b表示單詞邊界,表明該模式只匹配一個(gè)完整的單詞,而不再是單詞的一部分
-
[tT]:字符組,匹配t或者T,可以看作是第一個(gè)子模式 -
h:嘗試匹配小寫字母h -
[ceinry]:字符組,匹配組內(nèi)的字母,*表示零個(gè)或者多個(gè)
4.3 捕獲分組和后向引用
當(dāng)一個(gè)模式的全部的或者部分內(nèi)容由一對(duì)括號(hào)分組時(shí),就對(duì)內(nèi)容進(jìn)行捕獲并臨時(shí)存儲(chǔ)于內(nèi)存中
注意:引用的是捕獲的內(nèi)容,形式為:
\1
//或者
$1
\1或者$1引用的是第1個(gè)捕獲的分組,\2,$2引用的是第2個(gè)捕獲的分組,依次類推
簡(jiǎn)單使用,重新排序一行:

首先分別捕獲目標(biāo)分組,然后再Replace標(biāo)簽下的輸入框中輸入$2 $1,就可以看到高亮的文本,換了順序
4.4 非捕獲分組
非捕獲分組Non-Capturing Group,不會(huì)將其內(nèi)容存入內(nèi)存中,由于不儲(chǔ)存內(nèi)容,能提高性能,在恰當(dāng)復(fù)雜場(chǎng)景下,更適合使用
一開(kāi)始的(the|The|THE),可以改寫成非捕獲分組形式:
(?:the|The|THE)
- 原子分組
原子分組atomic-group:另一種非捕獲分組,可以將回溯操作關(guān)閉,只針對(duì)原子分組內(nèi)的部分,而不針對(duì)整個(gè)正則表達(dá)式
正則表達(dá)式處理過(guò)程緩慢的一個(gè)因素就是回溯操作,原因在于回溯操作會(huì)嘗試每一種可能性,會(huì)比較耗時(shí)和耗資源。如果一個(gè)回溯操作產(chǎn)生巨大的負(fù)面效應(yīng),就被稱為 災(zāi)難性回溯
原子分組,回溯操作,百度了下,看了看,暫時(shí)先不考慮了,先知道有這么個(gè)玩意。。。
5. 字符組
字符組,也被稱為 方括號(hào)表達(dá)式(backeted expression),有助于匹配特定的字符或者特定的字符序列

利用字符組,配11-20間的偶數(shù),以及a到z
字符組內(nèi)也可以使用簡(jiǎn)寫式,例如:
- 匹配空格和單詞字符
[\w\s]
//等價(jià)于
[_a-zA-Z \t\n\r]
5.1 字符組取反
- 字符組取反:
匹配與字符組內(nèi)容不匹配,不符合條件的的字符

字符組內(nèi)開(kāi)始的脫字符^意義就是NO,我不想匹配這些字符,^必須位于字符組的最開(kāi)始位置
6 匹配Unicode和其他字符
ASCII(American Standard Code for Inforation Interchange)美國(guó)信息交換標(biāo)準(zhǔn)碼定義了英文字符集,A到Z大寫和小字字母,以及控制字符,其他字符,一共含有128個(gè)
Unicode有10萬(wàn)個(gè)字符,它將ASCII碼表加入了基本Basic Latin拉丁碼表
伏爾泰先生的話,大意:
- 什么是寬容?它是人性的產(chǎn)物。我們生來(lái)都有缺陷和錯(cuò)誤,就讓我們?cè)彵舜说拇佬邪?!這才是大自然的第一法則
6.1 匹配Unicode字符

\u之后接的是十六進(jìn)制的00e9,不需要區(qū)分大小寫。在Unicode表中,é的代碼點(diǎn)為U+00E9,00e9對(duì)應(yīng)十進(jìn)制的233,超出了ASCII碼表0-127的范圍
除了使用十六進(jìn)制外,還可以使用八進(jìn)制來(lái)匹配字符,正則表達(dá)式的格式就是\后,接三位數(shù)字
\351
//等價(jià)于
、\u00e9
7. 量詞
- 配合練習(xí)的app:Reggy
7.1 貪心、懶惰和占有
指的是量詞的特性
- 貪心
量詞自身是貪心的。貪心的量詞首先會(huì)匹配整個(gè)字符串。嘗試匹配時(shí),會(huì)盡可能多的選定內(nèi)容,也就是整個(gè)輸入
量詞首次嘗試匹配整個(gè)字符串,如果失敗則回退一個(gè)字符后再次嘗試,這個(gè)過(guò)程則稱為回溯backtracking。每次會(huì)回退一個(gè)字符后,直到找到的匹配內(nèi)容或者沒(méi)有字符可以嘗試為止。而整個(gè)過(guò)程都會(huì)被記錄,對(duì)資源的消耗最大
整個(gè)過(guò)程就是:先吃盡把整個(gè)字符串,然后每次再吐一點(diǎn),慢慢咀嚼消化
- 懶惰
懶惰是另外一種策略。從目標(biāo)的起始位置開(kāi)始嘗試尋找匹配,每次檢查字符串的一個(gè)字符,尋找要匹配的內(nèi)容。最終,會(huì)嘗試匹配整個(gè)字符串。要使一個(gè)量詞稱為懶惰的, 必需要普通的量詞后添加一個(gè)?。意味著,每次只吃一點(diǎn)
- 占有
占有量詞會(huì)覆蓋整個(gè)目標(biāo)然后嘗試尋找匹配的內(nèi)容,但只會(huì)嘗試一次,并不會(huì)回溯。占有個(gè)量詞就是在普通的量詞前加一個(gè)+,意味著, 并不咀嚼而是直接吞咽,然后才去想吃什么
7.2 用*、+和?進(jìn)行匹配
- Kleene星號(hào)
這一命名是為了紀(jì)念正則表達(dá)式的發(fā)明人Stephen Kleene
.*:將會(huì)以貪心的方式匹配,匹配任意字符零次或者多次。

在Multiline模式下,9以及0兩行都會(huì)標(biāo)亮,在這個(gè)模式下,.號(hào)會(huì)匹配換行符,而一般情況下,.號(hào)并不會(huì)匹配換行符

*,+,?默認(rèn)都是貪心的量詞,第一次都會(huì)盡可能多地匹配字符
| 語(yǔ)法 | 描述 |
|---|---|
* |
零個(gè)或者多個(gè) |
+ |
一個(gè)或者多個(gè) |
? |
零個(gè)或者一個(gè) |
7.3 匹配特定次數(shù)

-
6{1}:匹配一個(gè)6 -
7{1,}:匹配多個(gè)7 -
8{3,5}:匹配888,8888,88888
7{1,} ---> 等價(jià)于: 7+
7* ---> 等價(jià)于: 7{0,}
7? ---> 等價(jià)于: 7{0,1}
| 語(yǔ)法 | 描述 |
|---|---|
{n} |
精確匹配n次 |
n, |
匹配n次或者更多次 |
m,n |
匹配m次至n次 |
0,1 |
零次或1次,與?相同 |
1,0 |
1次或更多,與+相同 |
0, |
零次或多次,與*相同 |
7.4 懶惰量詞

只匹配了兩個(gè)5,而不像貪心型量詞那樣,匹配5個(gè)數(shù)字5
| 語(yǔ)法 | 描述 |
|---|---|
?? |
懶惰匹配零次或一次,可選 |
+? |
懶惰匹配一次或者多次 |
*? |
懶惰匹配零次或多次 |
{n}? |
懶惰匹配n次 |
{n,}? |
懶惰匹配n次或多次 |
{m,n}? |
懶惰匹配m至n次 |
如果想要匹配最少而非最多數(shù)目的字符,可以使用懶惰量詞
7.5 占有式匹配
占有式匹配很像貪心式匹配,會(huì)選定盡可能多的內(nèi)容,但與貪心式不同的是,不會(huì)進(jìn)行回溯,所以速度也就最快。占有式量詞并不會(huì)放棄找到的內(nèi)容,匹配到內(nèi)容后就會(huì)占有,這也是為啥稱為占有式的原因

當(dāng)將表達(dá)式修改為.*+0時(shí),卻沒(méi)有匹配到任何字符,最后一行0并沒(méi)有被高亮
原因就是沒(méi)有回溯,首先一下子選定了所有了輸入,不再回過(guò)來(lái)查看。它會(huì)一下子揮霍了自己的財(cái)產(chǎn),一下子沒(méi)在結(jié)尾找到0,也不知道再?gòu)哪睦镩_(kāi)始找起
當(dāng)知道文本內(nèi)容時(shí),知道在哪里可以找到匹配,應(yīng)該考慮使用占有式量詞
| 語(yǔ)法 | 描述 |
|---|---|
?+ |
占有式匹配零次或者一次,可選 |
++ |
占有式匹配一次或多次 |
*+ |
占有式匹配零次或多次 |
{n}+ |
占有式匹配n次 |
{n,}+ |
占有式匹配n次或更多次 |
{m,n}+ |
占有式匹配m至n次 |
8. 簡(jiǎn)單實(shí)例
-
匹配北美電話號(hào)碼
匹配電話號(hào)碼
^\(?(?:\d{3})\)?[-.]?(?:\d{3})[-.]?(?:\d{4})$:
-
^:判定一行開(kāi)始或者主題詞開(kāi)始開(kāi)頭的零寬度斷言 -
\(?:判定(,可選 -
?:\d{3}:匹配連續(xù)三位數(shù)字的非捕獲分組 -
\)?:判定),可選 -
[-.]?:允許有可選的連字符-或者. -
?:\d{3}:匹配連續(xù)三位數(shù)字的非捕獲分組 -
[-.]?:允許有可選的連字符-或者. -
?:\d{4}:匹配連續(xù)四位數(shù)字的非捕獲分組 -
$:匹配一行或者主題詞的結(jié)尾
自己想到的一個(gè)改進(jìn),可能不合理:^\(?((?:\d{3})\)?[-.]?){2}?(?:\d{4})$
- 匹配郵箱

表達(dá)式 (?:[\w.-_]+)?(?:\w+)@(?:[\w._])+(?:\w+){1,}從Regexr Community 中的Email Address得到,網(wǎng)站給的是JavaScript下適用的,自己嘗試做了一點(diǎn)點(diǎn)修改,瞎改的,不要試圖拿來(lái)直接在自己的代碼中用。。。

偷個(gè)懶,直接截圖
9. 最后
書看是看完了,然而感覺(jué)啥都沒(méi)記住,需要多多練習(xí)。書后面3章看了看,沒(méi)做啥記錄
本人很菜,有錯(cuò)誤,請(qǐng)指出
共勉 :)
