GG資源網

正則表達式中使用方括弧定義自己的字元分類

問題描述:

python3 macOS系統
正則表達式中使用方括弧定義自己的字元分類,為什麼^要放在方括弧內?放在方括弧外為什麼會出錯?

網友觀點:

[^ ab] 放在裡邊表示不包含 a和 b
^ 放在外邊,表示以什麼開頭
兩個意思是不一樣的

字元串之正則表達式

推薦一個github程序員資料倉庫:

程序員免費資料倉

前言:

授人以魚不如授人以漁,大家在編程的時候總會遇到要查找某些複雜規則的字元串,例如在 linux 系統中,需要對多個文件里的某段代碼進行替換,你是不是還在每個文件打開逐一目標替換?如果你也有這樣的困惑那麼正則表達式就是你必須會的技能。

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 這個單詞的話,我們應該使用 \\bme\\b。

\\b 是正則表達式規定的一個特殊代碼(有些人叫它元字元,metacharacter),代表著單詞的開頭或結尾,也就是單詞的分界處。雖然通常英文的單詞是由空格,標點符號或者換行來分隔的,但是 \\b 並不匹配這些單詞分隔字元中的任何一個,它只匹配一個位置。

  • 假如你要找的是 me 後面不遠處跟著一個 james,你應該用 \\bme\\b.*\\bjames\\b。

這裡 . 是另一個元字元,匹配除了換行符以外的任意字元。* 同樣是元字元,不過它代表的不是字元,也不是位置,而是數量——它指定 * 前邊的內容可以連續重複使用任意次以使整個表達式得到匹配。

因此 .* 連在一起就意味著任意數量的不包含換行的字元。現在\\bme\\b.*\\bjames\\b的意思就很明顯了:先是一個單詞 me 然後是任意個任意字元(但不能是換行),最後是 james 這個單詞。

3、元字元

正則表達式由一些普通字元和一些元字元(metacharacters)組成。普通字元包括大小寫的字母和數字,而元字元則具有特殊的含義,要想真正的用好正則表達式,正確的理解元字元是最重要的事情。下表列出了常用的元字元

4、字元轉義

如果想查找元字元本身的話,比如查找 . ,或者 * ,就出現了問題:你沒辦法指定它們,因為它們會被解釋成別的意思。這時就得使用 \\ 來取消這些字元的特殊意義。因此,應該使用 . 和 *。當然,要查找 \\ 本身,也得用 \\。

例如:mayday\\.net 匹配 http://mayday.net ,C:\\\\Windows匹配C:\\Windows。

5、重複

已經看過了前面的 * , + 幾個匹配重複的方式了。下面是正則表達式中所有的限定符(指定數量的代碼:

6、字元類

要想查找數字、字母、數字、空白已經很簡單,因為已經有了對應這些字符集合的元字元,但是如果你想匹配沒有預定義元字元的字符集合(比如母音字母 a,e,i,o,u ),應該怎麼辦?

很簡單,你只需要在方括弧里列出它們就行了,像 [aeiou] 就匹配任何一個英文母音字母, [.?!] 匹配標點符號( . 或 ? 或 !)。

我們也可以輕鬆地指定一個字元範圍,像 [0-9] 代表的含意與 \\d 就是完全一致的:一位數字;同理 [a-z0-9A-Z_] 也完全等同於 \\w (如果只考慮英文的話)。

下面是一個更複雜的表達式:\\(?0\\d{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]?\\d\\d?)\\.){3}(2[0-4]\\d|25[0-5]|[01]?\\d\\d?)。

理解這個表達式的關鍵是理解2[0-4]\\d|25[0-5]|[01]?\\d\\d?,這裡就不細說了,大家應該能分析得出來它的意義。

9、貪婪與懶惰

當正則表達式中包含能接受重複的限定符時,通常的行為是匹配儘可能多的字元。以這個表達式為例: b.*c ,它將會匹配最長的以 b 開始,以 c 結束的字元串。如果用它來搜索 babac 的話,它會匹配整個字元串 babac 。這被稱為貪婪匹配。

有時,我們更需要懶惰匹配,也就是匹配儘可能少的字元。前面給出的限定符都可以被轉化為懶惰匹配模式,只要在它後面加上一個問號 ? 。這樣 .*? 就意味著匹配任意數量的重複,但是在能使整個匹配成功的前提下使用最少的重複。現在看看懶惰版的例子吧:

a.*?b 匹配最短的,以 a 開始,以 b 結束的字元串。如果把它應用於 aabab 的話,它會匹配 aab(第一到第三個字元)和 ab( 第四到第五個字元)。

10、處理選項

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

一個經常被問到的問題是:是不是只能同時使用多行模式和單行模式中的一種?

答案是:不是。這兩個選項之間沒有任何關係,除了它們的名字比較相似(以至於讓人感到疑惑)以外。

11、提示

正則表達式內容還有很多,筆者這裡只列舉常用部分,讀者若想進一步學習,可在微軟專業正則表達式學習網站學習:

https://docs.microsoft.com/zh-cn/dotnet/standard/base-types/regular-expressions?redirectedfrom=MSDN

由於網站搬家,部分鏈接失效,如無法下載,請聯繫站長!謝謝支持!
1. 帶 [親測] 說明源碼已經被站長親測過!
2. 下載後的源碼請在24小時內刪除,僅供學慣用途!
3. 分享目的僅供大家學習和交流,請不要用於商業用途!
4. 本站資源售價只是贊助,收取費用僅維持本站的日常運營所需!
5. 本站所有資源來源於站長上傳和網路,如有侵權請郵件聯繫站長!
6. 沒帶 [親測] 代表站長時間緊促,站長會保持每天更新 [親測] 源碼 !
7. 盜版ripro用戶購買ripro美化無擔保,若設置不成功/不生效我們不支持退款!
8. 本站提供的源碼、模板、插件等等其他資源,都不包含技術服務請大家諒解!
9. 如果你也有好源碼或者教程,可以到審核區發布,分享有金幣獎勵和額外收入!
10.如果您購買了某個產品,而我們還沒來得及更新,請聯繫站長或留言催更,謝謝理解 !
GG資源網 » 正則表達式中使用方括弧定義自己的字元分類

發表回復

CAPTCHAis initialing...