內容標題
什麼是 RegEx ?
RegEx (Regular Expression)正則表達式,是用字元序列來作為搜尋樣式,以找出在文章或語句符合的內容,以便修改或取代。
舉個例子,我們假設 \s 是用來搜尋哪裡有空格,\d 是用來搜尋哪裡有數字,則我設定樣式 \s\d,就是希望尋找空白後接著數字的位置。因此在下面這段文字:
2 34 577 89
滿足的有 " 2"、" 5"、" 9"。
Regex的使用格式
基本上很多的程式語言,都支持 RegEx,雖然可能有些為差異,但絕大部分的格式是相通的。接下來會列出常用的格式,之後可以到這裡練習單純的 RegEx 語法。
- [(Text)]
中括號是用來搜尋括號裡面的文字,加了^,就是指排除:
Regex Format | 效果 |
---|---|
[agh] | 搜尋 a 或 g 或 h |
[a-g] | 搜尋 a 到 g 其中一個 |
[a-zA-Z] | 搜尋英文字母 |
[0-9] | 搜尋 0 到 9 |
[0-9][0-9] | 搜尋兩個數字,例如 12 、03 |
[^agh] | 搜尋除了 a 和 g 和 h 的文字 |
[^1-6] | 搜尋不是 1 到 6 的文字 |
- 選取字元
Regex Format | 效果 |
---|---|
. | 任意字元 |
* | 0 或多個字元,需搭配其他使用。例如 .* 代表任意長度文字。[0-9]* 代表搜尋任意長度的數字。 |
+ | 1 或多個字元,需搭配其他使用。例如 .+ 代表長度大於一的文字。[0-9]+ 代表搜尋長度大於一的數字。 |
例如,djkfsjlflj、939jfajfjlk 都可以用 .* 來做搜尋。0、984984390 都可以用 [0-9]*做搜尋。
- 特殊符號
Regex Format | 效果 |
---|---|
\s | 空白字元,包括 " ", "\t", "\n", "\r" |
\S | 非空白字元 |
\d | 數字 |
\D | 非數字 |
\w | 英文字母 |
\W | 非英文字母 |
{m} | 前面的 pattern 重複 m 次。例如: a{4} 就是找 "a" 4次 |
{m,n} | 前面的 pattern 重複 m 到 n 次 。例如: a{5,7} 就是找 "a" 5 或 6 或 7 次 |
^...$ | 從開頭到結尾。例如:^\d*$ 就是找一行的數字,而非部分,需整行滿足 |
(a|b) | 尋找 a 或 b。 例如:(hello|test) 就是找 hello 或 test |
Python 中的 RegEx
接下來我們來利用 Python 來實作 Regex。處理 RegEx 的套件在 re,因此我們要先 import:
import re
我們舉一些常見的函數,之後再深入操作。
Function | 用處 |
---|---|
findall | 回傳所有滿足 pattern 的格式,型別為 list |
split | 以 pattern 做為分割的條件,回傳 list |
sub | 以 pattern 做為搜尋格式,以新字串取代 |
search | 以 pattern 做為搜尋格式,回傳 Match Object |
findall
使用 findall 時,第一個參數要放 pattern,第二個參數要放欲尋找的內容,這邊用 code 做個例子,我們要搜尋一串數字,因此 pattern 會是 [0-9]+:import re # The message going to been search message = "Hi Mary2, what is your tellphone? Oh! Tom11, my tellphone number is 0909202020" # RegEx pattern pattern = "[0-9]+"; # match is a list which consist of all the matched format match = re.findall(pattern, message) # Print out the match print(match)
['2', '11', '0909202020']
split
使用 split 是將整串文字做分割,而分割的條件是 pattern。第一個參數是 pattern,第二個參數是 欲分割的字串,而第三個參數是分割次數,預設是全部完成。例如:import re # The message going to been search message = "Hi Mary2, what is your tellphone? Oh! Tom11, my tellphone number is 0909202020" # RegEx pattern pattern = "[0-9]+"; # match is a list which is splitted by the specific format match = re.split(pattern, message) # Print out the match print(match)
# 將所有數字都分割完成 ['Hi Mary', ', what is your tellphone? Oh! Tom', ', my tellphone number is ', '']
這邊我們給
split
第三個參數,分別是 1 和 2:import re # The message going to been split message = "Hi Mary2, what is your tellphone? Oh! Tom11, my tellphone number is 0909202020" # RegEx pattern pattern = "[0-9]+"; # A match object match1 = re.split(pattern, message, 1) match2 = re.split(pattern, message, 2) print(match1) print(match2)
# 只分割到 2 就停了 ['Hi Mary', ', what is your tellphone? Oh! Tom11, my tellphone number is 0909202020'] # 分割 2 和 11 後就停了 ['Hi Mary', ', what is your tellphone? Oh! Tom', ', my tellphone number is 0909202020']
sub
使用 sub 是將特定文字取代成新文字。第一個參數為 pattern,第二個參數為替代者,第三個參數為被取代者。例如:import re # The message going to been subsititute message = "Hi Mary2, what is your tellphone? Oh! Tom11, my tellphone number is 0909202020" # RegEx pattern pattern = "[0-9]+"; # A result text result = re.sub(pattern, "hello", message) print(result)
# 原本是數字的地方,現在都被取代成 hello 了 Hi Maryhello, what is your tellphone? Oh! Tomhello, my tellphone number is hello
search
上面我們有提到說使用 search 會回傳 match object 的物件。我們可以先把結果 print 出來看看長什麼樣:import re # The message going to been subsititute message = "Hi Mary2, what is your tellphone? Oh! Tom11, my tellphone number is 0909202020" # RegEx pattern pattern = "[0-9]+"; # A result text result = re.search(pattern, message) print(result)
# 這邊我們可以看到是一個 Match object <re.Match object; span=(7, 8), match='2'>
而 Match Object 有一些 properties 和 method 可以使用:
string
:回傳傳入的 textspan()
:回傳符合 pattern 的開始和結束位置group()
:回傳找到的結果
import re # The message going to been subsititute message = "Hi Mary2, what is your tellphone? Oh! Tom11, my tellphone number is 0909202020" # RegEx pattern pattern = "[0-9]+"; # A result text result = re.search(pattern, message) print(result.string); print(result.span()); print(result.group());
# result.string Hi Mary2, what is your tellphone? Oh! Tom11, my tellphone number is 0909202020 # result.span() (7, 8) # result.group() 2
從這邊我們可以發現,
search
只會搜尋一遍,找到第一個符合的就會停止!
結語
這次我們認識一些 RegEx 的用法,並且結合 Python 進行操作。事實上除了程式語言,有些 IDE 內搜尋文字的功能也可以使用 RegEx。除了這篇,我應該還會再寫一篇關於 shell command 內使用 RegEx 的方法。這次就先這樣了,掰掰~
參考來源
- Python RegEx from w3 school
- Introducing Python [ Bill Lubanovic ]
- Cheat sheet for Regex