正則表達式是一個特殊的字符序列,它能幫助你方便的檢查一個字符串是否與某種模式匹配。
下表整理了一些正則表達式中經常用到的語法:
語法 | 描述 | 表達式示例 | 匹配示例 | |
字符 | 普通字符 | 匹配自身 | abc | abc |
\t | 匹配一個製表符 | |||
\r | 匹配一個回車符 | |||
\n | 匹配一個換行符 | |||
\f | 匹配一個換頁符 | |||
\v | 匹配一個垂直製表符 | |||
. | 匹配任意除換行符'\n'外的字符 在DOTALL模式中也能匹配換行符 |
a.c | abc | |
^ | 匹配輸入字符串的開始位置 | |||
$ | 匹配輸入字符串的結束位置 | |||
\b | 匹配一個單詞邊界,即字與空格間的位置 | |||
\B | 匹配非單詞邊界 | |||
| | 指明兩項之間的選擇一個 | |||
[...] | 字符集,對應的位置可以是字符集中任意字符。 字符集中的字符可以逐個列出,也可以給出範圍,例如 [abc]或者[a-c]。 第一個字符如果是 ^ 則表示取反,如 [^abc]表示除abc外的任意字符。 所有的特殊字符在字符集中都失去原有的特殊含義。在字符集中如果要使用 ]、- 、^,可以在前面加上反斜槓,或把 ] 、- 放在第一個字符,把 ^ 放在非第一個字符。 |
a[]a-z\[\-^]c | a[c a]c abc a-c a^c |
|
預定義字符集 | \d | 數字:[0-9] | a\dc | a6c |
\D | 非數字:[^0-9] 或者[^\d] | a\Dc | abc | |
\s | 空白字符:[空格\t\r\n\f\v] | a\sc | a c | |
\S | 非空白字符:[^\s] | a\Sc | abc | |
\w | 單詞字符:[A-Za-z0-9_] | a\wc | a_c | |
\W | 非單詞字符:[^\w] | a\Wc | a c | |
數量詞 | * | 匹配前一個字符任意次(0次、1次、...) | abc*d | abd abccd |
+ | 匹配前一個字符1次或多次 | abc+d | abcd abccd |
|
? | 匹配前一個字符0次或1次 | abc?d | abd abcd |
|
{n} {n,} {n,m} |
匹配前一個字符n次 匹配前一個字符至少n次 匹配前一個字符至少n次,最多m次 |
abc{3}d | abcccd |
注意:*、+限定符都是貪婪的,因爲它們會儘可能多的匹配文字,只有在它們的後面加上一個?就可以實現非貪婪或最小匹配。
Python 自1.5版本起增加了re 模塊,使得 Python 語言擁有全部的正則表達式功能,常用正則表達式的方法有如下幾個:
- re.compile(pattern, flags=0) # 編譯,獲取一個正則表達式對象用於匹配和替換
- pattern.match() # 對整個字符串進行匹配
- pattern.search() # 找一個
- pattern.findall() # 找所有
- pattern.sub() # 替換
compile方法中的 flags 參數用於控制正則表達式的匹配方式,如:是否區分大小寫,多行匹配等等。
re.I | 使匹配對大小寫不敏感 |
re.L | 做本地化識別(locale-aware)匹配 |
re.M | 多行匹配,影響 ^ 和 $ |
re.S | 使 . 匹配包括換行在內的所有字符 |
re.U | 根據Unicode字符集解析字符。這個標誌影響 \w, \W, \b, \B. |
re.X | 該標誌通過給予你更靈活的格式以便你將正則表達式寫得更易於理解。 |
match方法
match方法嘗試從字符串的起始位置與模式進行匹配,如果匹配成功的話,會返回一個包含了所有匹配分組的結果對象,否則返回None。
import re
match_str = 'Cats are smarter than dogs'
match_pattern = re.compile(r'(.*) are (.*?) .*', re.M | re.I)
match_ret = match_pattern.match(match_str)
if match_ret:
print("match_ret.group(0) : ", match_ret.group(0))
print("match_ret.group(1) : ", match_ret.group(1))
print("match_ret.group(2) : ", match_ret.group(2))
else:
print("No match!!")
print(match_ret.groups())
程序打印結果:
match_ret.group(0) : Cats are smarter than dogs
match_ret.group(1) : Cats
match_ret.group(2) : smarter
('Cats', 'smarter')
search方法
search方法會從左至右掃描整個字符串並返回第一個與模式匹配成功的部分字符串。
import re
search_str = 'Big fish eat small fish, small fish eat shrimp'
search_pattern = re.compile(r'(.*) fish .*', re.M | re.I)
search_ret = search_pattern.match(search_str)
if search_ret:
print("search_ret.group(0) : ", search_ret.group(0))
print("search_ret.group(1) : ", search_ret.group(1))
else:
print("No search!!")
程序打印結果:
search_ret.group(0) : Big fish eat small fish, small fish eat shrimp
search_ret.group(1) : Big fish eat small fish, small
findall方法
findall方法會在字符串中找到與模式匹配的所有子串,並返回一個列表,如果沒有找到匹配的字符串,則返回空列表。
import re
find_str = 'Big fish eat small fish, small fish eat shrimp'
find_pattern = re.compile(r'(\S* fish)', re.M | re.I)
find_ret = find_pattern.findall(find_str)
print(find_ret)
程序打印結果:
['Big fish', 'small fish', 'small fish']
另外還有一個finditer方法和findall很類似,也是在字符串中找到正則表達式所匹配的所有子串,但是會把它們作爲一個迭代器返回。
find_str = 'Big fish eat small fish, small fish eat shrimp'
find_pattern = re.compile(r'(\S* fish)', re.M | re.I)
iter = find_pattern.finditer(find_str)
for match in iter:
print(match.group())
sub方法
sub方法用來使用正則表達式對與模式匹配的子串進行替換,可以通過count參數來指定替換次數。
import re
sub_str = 'Big fish eat small fish, small fish eat shrimp'
sub_pattern = re.compile(r'(\S* fish)', re.M | re.I)
sub_ret = sub_pattern.sub('fish', sub_str, count=3)
print(sub_ret)
程序打印結果:
fish eat fish, fish eat shrimp
與sub方法類似地,有一個split方法能夠利用與正則模式匹配的子串將字符串進行分割並將分割後的結果放入列表返回。
split_str = 'Big fish eat small fish, small fish eat shrimp'
split_pattern = re.compile(r'(\S* fish)', re.M | re.I)
split_ret = split_pattern.split(sub_str,maxsplit=0)
print(split_ret)
程序打印結果:
['', 'Big fish', ' eat ', 'small fish', ', ', 'small fish', ' eat shrimp']