正則表達式

一、正則表達式介紹

一個正則表達式是一種從左到右匹配主體字符串的模式。
“Regular expression”這個詞比較拗口,我們常使用縮寫的術語“regex”或“regexp”。
正則表達式可以從一個基礎字符串中根據一定的匹配模式替換文本中的字符串、驗證表單、提取字符串等等。

二、基本語法

2.1 匹配符號

符號 說明
\b 匹配邊界,即字與空格間的位置。(\b所在位置的左右兩個字符有一個是\W,即不是A-Z,a-z,0-9,_)
\B 非單詞邊界匹配。
\d 匹配0-9中任意一個數字字符
\D 匹配除0-9外的非數字字符,等同于[^\d]
\f 匹配一個換頁符
\n 匹配一個換行符
\p 匹配 CR/LF(等同于 \r\n),用來匹配 DOS 行終止符
\r 匹配一個回車符
\s 匹配空格、制表符、換行符等空白字符
\S 匹配非空白字符
\t 匹配一個制表符
\v 匹配一個垂直制表符
\w 匹配A-Z,a-z,0-9和_中任意一個
\W 非單詞字符,等同于: [^\w]
. 匹配一個任意的字符,不匹配換行符。如 .* 匹配任意字符串
\p{L} 表示Unicode字母
\p{N} 表示Unicode數字

2.2 特殊含義符號

符號 說明
\ 轉義,用于指定 { } [ ] / \ + * . $ ^|?這些特殊字符。如果想要匹配這些特殊字符則要在其前面加上反斜線 \。
^ 表示一行的開頭,而在[]內表示取反
$ 匹配一行的結束,如 R$ 表示以R結尾的行
[] 表示匹配某個范圍內的字符,正則表達式特殊字符被放到中括號中,失去特殊含義,除了"^"和"-" 。如[a-z]表示匹配一個小寫字母;[^a-z]表示匹配一個非小寫字母。
() 作為一個整體進行匹配,如(ab)+表示匹配ab一次或多次,如 (cat|dog)+ 表達匹配一次或多次cat或dog
| 或運算符就表示或,用作判斷條件。

2.3 量詞

通過量詞可以設置一個內容出現的次數 ,量詞只對它前邊的一個內容起作。

符號 說明
{3} 匹配三個
{3,6} 匹配3到6個(默認貪婪模式,往多的匹配)
{3,6}? 匹配3到6個,?表示非貪婪模式,即匹配最少個數。
? 匹配前面元字符0次或1次,相當于{0,1};也會被用來表示懶惰匹配,如<.+?>可以匹配html標簽
+ 一個或多個,相當于{1,}
* 匹配任意個(貪心匹配),相當于{0,}

2.4 零寬斷言

先行斷言和后發斷言都屬于非捕獲簇(不捕獲文本 ,也不針對組合計進行計數)。
先行斷言用于判斷所匹配的格式是否在另一個確定的格式之前,匹配結果不包含該確定格式(僅作為約束)。

例如,我們想要獲得所有跟在 $ 符號后的數字,我們可以使用正后發斷言 (?<=\$)[0-9\.]*
這個表達式匹配 $ 開頭,之后跟著 0,1,2,3,4,5,6,7,8,9,. 這些字符可以出現大于等于 0 次。

零寬度斷言如下:

符號 描述
?= 正先行斷言-存在
?! 負先行斷言-排除
?<= 正后發斷言-存在
?<! 負后發斷言-排除

2.4.1 ?=... 正先行斷言

?=... 正先行斷言,表示第一部分表達式之后必須跟著 ?=...定義的表達式。

返回結果只包含滿足匹配條件的第一部分表達式。
定義一個正先行斷言要使用 (?=...)

  • 如果將正先行斷言式放在匹配式的后面,則表示匹配式后需要滿足正先行斷言式。

  • 如果將正先行斷言式放在匹配式的前面,則表示使用正先行斷言式對匹配到的結果進行篩選。

例:

現在有文本如下

The fat cat sat on the mat.

使用正先行斷言(T|t)he(?=\sfat)進行正則匹配,即 Thethe 后面緊跟著 (空格)fat。也可以使用表達式(?=The\sfat)The進行匹配。

最終得到匹配的文本如下

The

例:

至少一個大寫字母和一個小寫字母,可以使用表達式 (?=.*?[a-z])(?=.*?[A-Z]).+

2.4.2 ?!... 負先行斷言

負先行斷言 ?! 用于篩選所有匹配結果,篩選條件為 其后不跟隨著斷言中定義的格式。
正先行斷言 定義和 負先行斷言 一樣,區別就是 = 替換成 ! 也就是 (?!...)

例:
有文本如下

The fat cat sat on the mat.

使用負先行斷言(T|t)he(?!\sfat)進行正則匹配,即 Thethe 后面沒有 (空格)fat文本。

最終得到匹配的文本如下

the

2.4.3 ?<= ... 正后發斷言

正后發斷言 記作(?<=...) 用于篩選所有匹配結果,篩選條件為 其前跟隨著斷言中定義的格式。

  • 如果將正后發斷言式放在匹配式的前面,則表示匹配式前需要滿足正后發斷言式。

  • 如果將正后發斷言式放在匹配式的后面,則表示使用正后發斷言式對匹配到的結果進行篩選。

例:

表達式 `` 匹配 fatmat,且其前跟著 Thethe

有文本如下

The fat cat sat on the mat.

使用正后發斷言(?<=The\s)(fat|mat)進行正則匹配,即 fatmat前跟隨著 The文本。也可以使用匹配式(fat|mat)(?<=The\sfat)進行匹配。

最終得到匹配的文本如下

fat

例:

匹配文本

我喜歡你

使用匹配式(?<=我)喜歡(?=你)

2.4.4 ?<!... 負后發斷言

負后發斷言 記作 (?<!...) 用于篩選所有匹配結果,篩選條件為 其前不跟隨著斷言中定義的格式。

例:

有文本如下

The fat cat sat on the mat.

使用正后發斷言(?<!The\s)(fat|mat)進行正則匹配,即 fatmat前不跟隨著 The文本。

最終得到匹配的文本如下

mat

2.5 標志

標志也叫模式修正符,因為它可以用來修改表達式的搜索結果。
這些標志可以任意的組合使用,它也是整個正則表達式的一部分。

標志 描述
i 忽略大小寫。
g 全局搜索。
m 多行修飾符:錨點元字符 ^ $ 工作范圍在每行的起始。
s dotall
u Unicode
y 粘性(stucky)

2.5.1 全局搜索 (Global search)

修飾符 g 常用于執行一個全局搜索匹配,即(不僅僅返回第一個匹配的,而是返回全部)。

例:

表達式 /.(at)/g 表示搜索 任意字符(除了換行)+ at,并返回全部結果。

2.5.2 忽略大小寫 (Case Insensitive)

修飾語 i 用于忽略大小寫。

例:

如,表達式 /The/gi 表示在全局搜索 The,在后面的 i 將其條件修改為忽略大小寫,則變成搜索 theThe

2.5.3 多行修飾符 (Multiline)

多行修飾符 m 常用于執行一個多行匹配。

像之前介紹的 ^和$ 用于檢查格式是否是在待檢測字符串的開頭或結尾。但我們如果想要它在每行的開頭和結尾生效,我們需要用到多行修飾符 m

例如,表達式 /at(.)?$/gm 表示小寫字符 a 后跟小寫字符 t ,末尾可選除換行符外任意字符。根據 m 修飾符,現在表達式匹配每行的結尾。

2.6 捕獲組

2.6.1 捕獲分組

在正則表達式中還提供了一種將表達式分組的機制,當使用分組時,除了獲得整個匹配。還能在匹配中選擇每一個分組。

要實現分組,使用()即可。

例:

文本如下

張三:0571-88551166

使用表達式/(\d{4})-(\d{8})/g,匹配得到文本 0571-8855116.

那么這個文本實際分為了兩組,第一組為0571,第二組為8855116.

2.6.2 非捕獲分組

有時候,我們并不需要捕獲某個分組的內容,但是又想使用分組的特性。

這時候就可以使用非捕獲分組(?:表達式),從而不捕獲數據,還能使用分組的功能。

2.6.3 分組回溯引用

正則表達式提供了一種引用之前匹配分組的機制,有些時候,我們或許會尋找到一個子匹配,該匹配接下來會再次出現。

例:

文本如下

<font>提示</font>
<font>提示</bar>

希望匹配正確的標簽,可以使用 <(\w+?)>(.*?)<\/\1>這里\1表示第一個括號中的內容,這樣就可以使用回溯分組調用,調用第一個括號的內容。

最終匹配到了正確的文本

<font>提示</font>


注:在java程序中,可以使用 $n 來使用捕獲的第n個內容,如 string.replaceAll("<(.*)>", "$1 ");


三、經典正則表達式

  • 由26個字母和數字組成的字符串:^[A-Za-z0-9]+\$

  • 匹配中文字符:[\u4e00-\u9fa5]

  • 沒有空字符的且以tmp結尾的文件(^在中括號中表示取反,在中括號外表示開頭):[^ ]*.tmp

  • 匹配html標簽:<.+?> 只需要添加懶惰匹配符號?,讓<>來匹配每個標簽

  • 匹配顏色標簽符,如#ffffff:#[a-fA-F0-9]{6}\b,添加\b是為了防止#ffffffff這種被識別為顏色標簽符

  • 正整數*: ^\d+$

  • 負整數^-\d+$

  • 國內電話號碼:\d{3}-\d{8}|\d{4}-\d{7}

  • 手機國家號^+?[\d\s]{3,}$

  • 手機號^+?[\d\s]+(?[\d\s]{10,}$

  • 整數^-?\d+$

  • 用戶名^[\w\d_.]{4,16}$

  • 數字和英文字母^[a-zA-Z0-9]*$

  • 數字和應為字母和空格^[a-zA-Z0-9 ]*$

  • 密碼(至少一個大寫字母、至少一個小寫字母、至少一個數字、至少8個字符):/(?=.*?[a-z])(?=.*?[A-Z])(?=.*?(\d)).{8,}/g

  • 密碼^(?=^.{6,}$)((?=.*[A-Za-z0-9])(?=.*[A-Z])(?=.*[a-z]))^.*$

  • 郵箱^([a-zA-Z0-9._%-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4})*$

  • IP4 地址^((?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))*$

  • 純小寫字母^([a-z])*$

  • 純大寫字母^([A-Z])*$

  • URL^(((http|https|ftp):\/\/)?([[a-zA-Z0-9]\-\.])+(\.)([[a-zA-Z0-9]]){2,4}([[a-zA-Z0-9]\/+=%&_\.~?\-]*))*$

  • VISA 信用卡號^(4[0-9]{12}(?:[0-9]{3})?)*$

  • 日期 (MM/DD/YYYY)^(0?[1-9]|1[012])[- /.](0?[1-9]|[12][0-9]|3[01])[- /.](19|20)?[0-9]{2}$

  • 日期 (YYYY/MM/DD)^(19|20)?[0-9]{2}[- /.](0?[1-9]|1[012])[- /.](0?[1-9]|[12][0-9]|3[01])$

  • MasterCard 信用卡號^(5[1-5][0-9]{14})*$

IP地址(需要分為四段):
0-99:[1-9]?\d
100-199:1\d{2}
200-249:2[0-4]\d
250-256:25[0-5]
(([1-9]?\d|1\d{2}|2[0-4]\d|25[0-5]).){3}([1-9]?\d|1\d{2}|2[0-4]\d|25[0-5])

四、測試

正則在線測試工具
正則練習網站

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
禁止轉載,如需轉載請通過簡信或評論聯系作者。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,837評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,196評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,688評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,654評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,456評論 6 406
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,955評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,044評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,195評論 0 287
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,725評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,608評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,802評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,318評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,048評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,422評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,673評論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,424評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,762評論 2 372

推薦閱讀更多精彩內容