前言:
授人以魚不如授人以漁,大家在編程的時候總會遇到要查找某些複雜規則的字符串,例如在 linux 系統中,需要對多個文件里的某段代碼進行替換,你是不是還在每個文件打開逐一目標替換?如果你也有這樣的困惑那麼正則表達式就是你必須會的技能。
推薦一個github的程序員資料倉庫:
1、什麼是正則表達式
正則表達式是對字符串操作的一種邏輯公式,就是用事先定義好的一些特定字符、及這些特定字符的組合,組成一個 “規則字符串” ,這個 “規則字符串” 用來表達對字符串的一種過濾邏輯。換句話說,正則表達式就是記錄文本規則的代碼。
很可能你使用過 Windows 下用於文件查找的通配符(wildcard),也就是 * 和 ?。如果你想查找某個目錄下的所有的 pdf 文檔的話,可以直接搜索 *.pdf,如下:

在這裡,* 會被解釋成任意的字符串。和通配符類似,正則表達式也是用來進行文本匹配的工具,只不過比起通配符,它能更精確地描述你的需求。當然,代價就是更複雜,比如你可以編寫一個正則表達式,用來查找所有以 0 開頭,後面跟着 2-3 個數字,然後是一個連字號 “-” ,最後是 7 或 8 位數字的字符串(像 011-12345678 或 0856-7654321)。
2、入門
學習正則表達式的最好方法是從例子開始。
- 假如你在一篇英文期刊里查找 me,你可以使用正則表達式 me。
這幾乎是最簡單的正則表達式了,它可以精確匹配這樣的字符串:由兩個字符組成,前一個字符是 m, 後一個是 e。通常,處理正則表達式的工具會提供一個忽略大小寫的選項,如果選中了這個選項,它可以匹配 me, ME, Me, mE 這四種情況中的任意一種。
不幸的是,很多單詞里包含 hi 這兩個連續的字符,比如 me, mean, measure等等。用 me 來查找的話,這裡邊的 me 也會被找出來。如果要精確地查找 me 這個單詞的話,我們應該使用 bmeb。
b 是正則表達式規定的一個特殊代碼(有些人叫它元字符,metacharacter),代表着單詞的開頭或結尾,也就是單詞的分界處。雖然通常英文的單詞是由空格,標點符號或者換行來分隔的,但是 b 並不匹配這些單詞分隔字符中的任何一個,它只匹配一個位置。
- 假如你要找的是 me 後面不遠處跟着一個 james,你應該用 bmeb.*bjamesb。
這裡 . 是另一個元字符,匹配除了換行符以外的任意字符。* 同樣是元字符,不過它代表的不是字符,也不是位置,而是數量——它指定 * 前邊的內容可以連續重複使用任意次以使整個表達式得到匹配。
因此 .* 連在一起就意味着任意數量的不包含換行的字符。現在bmeb.*bjamesb的意思就很明顯了:先是一個單詞 me 然後是任意個任意字符(但不能是換行),最後是 james 這個單詞。
3、元字符
正則表達式由一些普通字符和一些元字符(metacharacters)組成。普通字符包括大小寫的字母和數字,而元字符則具有特殊的含義,要想真正的用好正則表達式,正確的理解元字符是最重要的事情。下表列出了常用的元字符

4、字符轉義
如果想查找元字符本身的話,比如查找 . ,或者 * ,就出現了問題:你沒辦法指定它們,因為它們會被解釋成別的意思。這時就得使用 來取消這些字符的特殊意義。因此,應該使用 . 和 *。當然,要查找 本身,也得用 。
例如:mayday.net 匹配 mayday.net ,C:\Windows匹配C:Windows。
5、重複
已經看過了前面的 * , + 幾個匹配重複的方式了。下面是正則表達式中所有的限定符(指定數量的代碼:

6、字符類
要想查找數字、字母、數字、空白已經很簡單,因為已經有了對應這些字符集合的元字符,但是如果你想匹配沒有預定義元字符的字符集合(比如元音字母 a,e,i,o,u ),應該怎麼辦?
很簡單,你只需要在方括號里列出它們就行了,像 [aeiou] 就匹配任何一個英文元音字母, [.?!] 匹配標點符號( . 或 ? 或 !)。
我們也可以輕鬆地指定一個字符範圍,像 [0-9] 代表的含意與 d 就是完全一致的:一位數字;同理 [a-z0-9A-Z_] 也完全等同於 w (如果只考慮英文的話)。
下面是一個更複雜的表達式:(?0d{2}[) -]?d{8}。
這個表達式可以匹配幾種格式的電話號碼,像 011-22884499 ,或 0845652452 等。我們對它進行一些分析吧:首先是一個轉義字符 (,它能出現 0 次或 1 次 (?),然後是一個 0,後面跟着 2 個數字 (d{2}),然後是)或-或空格中的一個,它出現 1 次或不出現(?),最後是 8 個數字(d{8})。
7、反義
有時需要查找不屬於某個能簡單定義的字符類的字符。比如想查找除了數字以外,其它任意字符都行的情況,這時需要用到反義

例子:
S+ 匹配不包含空白符的字符串。 <a[^>]+> 匹配用尖括號括起來的以 a 開頭的字符串
8、分組
我們已經提到了怎麼重複單個字符(直接在字符後面加上限定符就行了);但如果想要重複多個字符又該怎麼辦?可以用小括號來指定子表達式(也叫做分組),然後就可以指定這個子表達式的重複次數了,也可以對子表達式進行其它一些操作。
(d{1,3}.){3}d{1,3} 是一個簡單的 IP 地址匹配表達式。要理解這個表達式,請按下列順序分析它:d{1,3} 匹配 1 到 3 位的數字,(d{1,3}.){3} 匹配三位數字加上一個英文句號(這個整體也就是這個分組)重複 3 次,最後再加上一個一到三位的數字(d{1,3})。
可是也將匹配256.300.777.888這種不可能存在的 IP 地址。如果能使用算術比較的話,或許能簡單地解決這個問題,但是正則表達式中並不提供關於數學的任何功能,所以只能使用冗長的分組,選擇,字符類來描述一個正確的 IP 地址:((2[0-4]d|25[0-5]|[01]?dd?).){3}(2[0-4]d|25[0-5]|[01]?dd?)。
理解這個表達式的關鍵是理解2[0-4]d|25[0-5]|[01]?dd?,這裡就不細說了,大家應該能分析得出來它的意義。
9、貪婪與懶惰
當正則表達式中包含能接受重複的限定符時,通常的行為是匹配儘可能多的字符。以這個表達式為例: b.*c ,它將會匹配最長的以 b 開始,以 c 結束的字符串。如果用它來搜索 babac 的話,它會匹配整個字符串 babac 。這被稱為貪婪匹配。
有時,我們更需要懶惰匹配,也就是匹配儘可能少的字符。前面給出的限定符都可以被轉化為懶惰匹配模式,只要在它後面加上一個問號 ? 。這樣 .*? 就意味着匹配任意數量的重複,但是在能使整個匹配成功的前提下使用最少的重複。現在看看懶惰版的例子吧:
a.*?b 匹配最短的,以 a 開始,以 b 結束的字符串。如果把它應用於 aabab 的話,它會匹配 aab(第一到第三個字符)和 ab( 第四到第五個字符)。

10、處理選項
上面介紹了幾個選項如忽略大小寫,處理多行等,這些選項能用來改變處理正則表達式的方式。下面是 .Net 中常用的正則表達式選項:

一個經常被問到的問題是:是不是只能同時使用多行模式和單行模式中的一種?
答案是:不是。這兩個選項之間沒有任何關係,除了它們的名字比較相似(以至於讓人感到疑惑)以外。
11、提示
正則表達式內容還有很多,筆者這裡只列舉常用部分,讀者若想進一步學習,可在微軟專業正則表達式學習網站學習:
正則表達式語法支持情況如下圖:

原創文章,作者:投稿專員,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/280053.html
微信掃一掃
支付寶掃一掃