# 在Python中使用正則
###### tags: `人生苦短,我學Python`
## 正則表達式的語法
:::info
在處理字串時,經查需要查找符合某些複雜規則的字符串,簡單來說,正則就是紀錄文本規則的程式碼。
:::
## 行定位符
* 用來表達字符串的邊界,"^"表示行的開始,"$"表示行的結尾
```python=
#test python test
# 表示前頭匹配
^test
# 表示尾巴匹配
$test
# 任意匹配
test
```
## 元字符
* 舉例
```python=
\bmr\w*\b
# 匹配字母以mr開頭,
# 從某個單詞處開始(\b),然後匹配mr,
# 接下來是任意字數的字母或數字(\w*),
# 最後是單詞結尾處的\b
# 所以 mrsoft, mr5566ss......皆滿足
```
## 重複
* 在正則裡,使用"\w*"匹配任意數量的字母或字符
* 常用限定符
| ? | 匹配前面的字符,一次或零次 | colou?r => color / colour |
| -------- | -------- | -------- |
| + | 匹配前面的字符,一次或零次 | go+gle => gogle / gooo...gle |
|*|匹配前面的字符,零次或多次|go*gle => ggle / goo...gle
|{n}|匹配前面的字符n次|go{2}gle => 只能表達 google|
|{n,}|匹配前面的字符最少n次|go{2,}gle => google / gooo..gle
|{n, m}|匹配前面的字符最少n次,最多m次|go{0,2}gle => ggle, gogle, google
## 字符類
:::warning
\d 匹配任何十進制數;同 [0-9]。
\D 匹配任何非數字字符;同 [^0-9]。
\s 匹配普通的空白字符;類似的 [ \t\n\r\f\v]。
\S 匹配任何非空閒字符;它等效 [^ \t\n\r\f\v]。
\w 匹配任何字母數字字符;它等效 [a-zA-Z0-9_]。
\W 匹配任何非字母數字字符;它等效 [^a-zA-Z0-9_]。
:warning:如果想給定一個字符串值中的任意漢字,可以使用[\u4e00-\u9fa5],如果是要連續多個漢字的話,可以使用[\u4e00-\u9fa5]+
:::
## 排除字符
* 表達一個不是字母的字符
```python=
[^a-zA-Z]
```
## 選擇字符
* 匹配身分證號碼(10碼)
```python=
^[A-Z]\\d{1}[1|2]\\d{8}$
```
## 轉義字符
* IP位址示範
```python=
# 127.0.0.1
[1-9]{1, 3}\.[0-9]{1, 3}\.[0-9]{1, 3}\.[0-9]{1, 3}
# 使用 . 的時候,需要使用轉義字符(\)
```
## 分組
```python=
(thir|four)th
# 分成thirth跟fourth兩組
```
## 在Python中使用正則
```python=
# 匹配非字母
[^a-zA-Z]
# 需要進行轉義
"\\bm\\w*\\b"
# 可能會出現大量的反斜槓
# 所以需要在前面加r或R
r"\bm\w*\b"
```
## 使用re模組實踐正則
:::danger
```python=
import re
```
:warning:在使用之前,必須引用此模組
:::
## 匹配字符串
* 使用match()函數
```python=
# re.match(pattern, string, [flags])
# pattern表示模式字符串,由正要匹配的正則轉而來換
# string字符串
#flags可選參數,表示標誌位
import re
test = re.match(r"re", rex)
print(test)
# <re.Match object; span=(0, 2), match='re'>
# match.start()找開頭
# match.end()找尾
# match.span()找元組
# match.group()找匹配數據
```
* 使用serach()函數
```python=
# 在尋找第一個匹配的值
import re
test = re.search(r"r\w+", "rrrrex_rrrex")
print(test)
# <re.Match object; span=(0, 12), match='rrrrex_rrrex'>
```
* 使用findall()函數
```python=
# 尋找在字串中所有符合的字串
import re
test = re.findall(r"r\w+", "rex rrr rrrrrl")
print(test)
# ['rex', 'rrr', 'rrrrrl']
```
* 檢驗台灣手機號碼
```python=
import re
test = re.match(r'\d\d\d\d-\d\d\d-\d\d\d', '0935-446-889')
print(test)
# <re.Match object; span=(0, 12), match='0935-446-889'>
```
## 替換字串符
```python=
# re.sub(pattern, repl, string, count, flags)
# repl表示替換的字串符
import re
pat = r"re\d{5}"
string_test = "re20011"
result = re.sub(pat, "re55556", string_test)
print(result)
# re55566
```
## 切割自符串
```python=
# re.split(pattern, string, [maxsplit], [flags])
import re
pat = r"[a|b]"
string_test = "a bc abd absdssaac"
result = re.split(pat, string_test)
print(result)
# ['', ' ', 'c ', '', 'd ', '', 'sdss', '', 'c']
```
:::warning
:warning: 本文只有做非常淺白的說明,如果要更深入一步,則需查閱多方資料:warning:
:::
{%hackmd S1DMFioCO %}