正則表達式(一)
一、正則表達式簡介
用通俗的話來講,正則表達式是一種特殊的字元串,我們可以使用它來非常方便地對輸入的字元串進行判斷或資訊的提取,例如我們可以使用\d+
來判斷這個字元串是否表示一個數字,這大大簡化了我們判斷字元串正誤的流程也大大提高了我們提取字元資訊的能力(例如可以直接使用正則表達式編寫爬蟲程式)。
二、正則表達式知識點
參考資料:
//github.com/cdoco/learn-regex-zh
//www.liaoxuefeng.com/wiki/1252599548343744
使用的正則表達式可視化平台:
1. 元字元
各個元字元及描述如下:
元字元 | 描述 |
---|---|
. |
匹配除換行符以外的任意字元。 |
[ ] |
字元類,匹配方括弧中包含的任意字元。 |
[^ ] |
否定字元類。匹配方括弧中不包含的任意字元 |
* |
匹配前面的子表達式零次或多次 |
+ |
匹配前面的子表達式一次或多次 |
? |
匹配前面的子表達式零次或一次,或指明一個非貪婪限定符。 |
{n,m} |
花括弧,匹配前面字元至少 n 次,但是不超過 m 次。 |
(xyz) |
字元組,按照確切的順序匹配字元 xyz。 |
\| |
分支結構,匹配符號之前的字元或後面的字元。 |
\ |
轉義符,它可以還原元字元原來的含義,允許你匹配保留字元 [ ] ( ) { } . * + ? ^ $ \ | |
^ |
匹配行的開始 |
$ |
匹配行的結束 |
1.1 英文句號.
.
可以匹配除換行符以外的任意字元,例如我們可以使用a.b
來匹配aob
,a1b
等等:
1.2 方括弧[]
方括弧中包括的字元構成了一個字符集,例如[0123456789]
構成了包含所有數字的字符集
例如上面的例子,[Tt]he
可以匹配The
和the
。
而字符集中的.
則單純地代表點號,即在字符集中的元字元符號不會被當做通配符處理。
此外我們希望表示1~9構成的字符集時,我們可以簡寫為[1-9]
,而字母也是同理,例如我們可以使用這個字符集來描述C語言中的標識符:[a-zA-Z0-9_]
(即字母,數字,下劃線)
1.3 否定字符集
當在方括弧構成的字符集前面加上^
號,例如可以這樣表示非數字字符集:[^0-9]
示例:
1.4 重複符號
表示重複的符號有下面三個:
*
:前面的字元重複 0~n次+
:前面的字元重複 1~n次(即至少需要出現一次)?
:前面的字元重複 0~1次(即前面的字元可出現也可以不出現,一般用於可選字元)
示例:
符號 | 效果 |
---|---|
* 符號 |
![]() ![]() |
+ 符號 |
![]() ![]() |
? 符號 |
![]() ![]() |
1.5 花括弧{}
正則表達式中花括弧用於表示精確的匹配次數,如數字字元出現3次,可以使用[0-9]{3}
來表示。
寫法有以下三種:
{m}
:前面的字元出現m次{m,n}
:前面的字元出現m~n次{n,}
:前面的字元出現≥n次
1.6 字元組()
字元組是一組寫在圓括弧內的子模式 (...)
。
如果我們把一個量詞放在一個字元之後,它會重複前一個字元。 但是,如果我們把量詞放在一個字元組之後,它會重複整個字元組。例如正則表達式 (ab)*
表示匹配零個或多個的字元串「ab」。
此外,在字元組中我們還可以使用元字元|
來表示或關係,例如:
1.7 分支結構|
我們在1.6中已經使用過|
來表示邏輯或關係了,其實這個分支結構不僅可以放置在字元組中,也可以放置在最外層:
1.8 轉義特殊字元
因為許多字元被用於作為元字元了,因此這些字元如果我們希望作為正常字元進行匹配,我們則需要在它們前面加上轉義符\
,例如希望表示.
字元,我們可以使用\.
示例(選取英文句號前第一個單詞):
1.9 定位符
定位符有兩個:
^
:放在表達式的最前面,子串需要滿足其他的表達式規則之外,還必須在輸入字元串的最前面$
:放在表達式的最後面,子串需要滿足其他的表達式規則之外,還必須在輸入字元串的最後面
示例:
符號 | 效果 |
---|---|
^ |
![]() ![]() |
$ |
![]() ![]() |
2. 簡寫字符集
正則表達式為常用的字符集和常用的正則表達式提供了簡寫。簡寫字符集如下:
簡寫 | 描述 |
---|---|
. |
匹配除換行符以外的任意字元 |
\w |
匹配所有字母和數字的字元:[a-zA-Z0-9_] |
\W |
匹配非字母和數字的字元:[^\w] |
\d |
匹配數字:[0-9] |
\D |
匹配非數字:[^\d] |
\s |
匹配空格符:[\t\n\f\r\p{Z}] |
\S |
匹配非空格符:[^\s] |
3. 斷言
後行斷言和先行斷言有時候被稱為斷言,它們是特殊類型的 非捕獲組(用於匹配模式,但不包括在匹配列表中)。當我們在一種特定模式之前或者之後有這種模式時,會優先使用斷言。 例如我們想獲取輸入字元串 $4.44 and $10.88
中帶有前綴 $
的所有數字。我們可以使用這個正則表達式 (?<=\$)[0-9\.]*
,表示:獲取包含 .
字元且前綴為 $
的所有數字。
用通俗的話來說就是:我希望匹配的東西在某個模式(需要用正則表達式描述這個模式)的前面或者後面,例如我當前有一個html文件,我需要得到所有a標籤和p標籤中的內容,此時我可以使用某個表達式來描述這兩個標籤,進而定位匹配到標籤內部的內容。
以下是正則表達式中使用的斷言:
符號 | 描述 | 作用 |
---|---|---|
?= |
正向先行斷言 | 結果集元素後面有這個模式 |
?! |
負向先行斷言 | 結果集元素後面沒有這個模式 |
?<= |
正向後行斷言 | 結果集元素前面有這個模式 |
?<! |
負向後行斷言 | 結果集元素前面沒有這個模式 |
各個斷言的寫法基本都是一樣的,基本都是(斷言符號+斷言模式)
。
3.1 正向先行斷言
例如還是這個字元串:The fat cat sat on the mat.
我們希望匹配到所有fat
前面的The
,我們可以這樣寫:
3.2 負向先行斷言
負向先行斷言則是用於限制後面沒有這個模式,例如希望匹配到所有後面沒有\sfat
的 The
或 the
:
即後面凡是有這個模式的都被過濾掉。
3.3 正向後行斷言
從輸入字元串中獲取在單詞 The
或 the
之後的所有 fat
和 mat
單詞:
3.4 負向後行斷言
在輸入字元中獲取所有不在 The
或 the
之後的所有單詞 cat
: