Python筆記---常用正則表達式練習


正則表達式的作用不言而喻,網上也有很多基礎規則的列表。Python的正則表達式處理主要基於Python的re模塊,這裏主要基於幾個常用的元字符做一些基本介紹和代碼驗證。代碼塊中省略了import re

1. \d :匹配一個數字字符。等價於 [0-9]。

示例代碼塊:

a = 'C0dke3rlt443~!0ydwo73d8'
r = re.findall(r'\d', a)
print(f'r : {r}')

輸出結果:

r : ['0', '3', '4', '4', '3', '0', '7', '3', '8']

2. \D:匹配一個非數字字符。等價於 [^0-9]。

示例代碼塊:

a = 'C0dke3rlt443~!0ydwo73d8'
r = re.findall(r'\D', a)
print(f'r : {r}')

輸出結果:

r : ['C', 'd', 'k', 'e', 'r', 'l', 't', '~', '!', 'y', 'd', 'w', 'o', 'd']

3. [ ]

[xyz]:字符集合。匹配所包含的任意一個字符。
[^xyz]:負值字符集合。匹配未包含的任意字符。

示例代碼塊:

b = 'abc, acc, adc, aec, afc, ahc'
r1 = re.findall('a[cf]c',b)
r2 = re.findall('a[^cf]c',b)
print(f'r1 : {r1}')
print(f'r2 : {r2}')

輸出結果:

r1 : ['acc', 'afc']
r2 : ['abc', 'adc', 'aec', 'ahc']

4. -

[a-z]: 字符範圍。匹配指定範圍內的任意字符
[^a-z]: 負值字符範圍。匹配任何不在指定範圍內的任意字符。

示例代碼塊:

b = 'abc, acc, adc, aec, afc, ahc'
r1 = re.findall('a[c-f]c', b)
r2 = re.findall('a[^c-f]c', b)
print(f'r1 : {r1}')
print(f'r2 : {r2}')

輸出結果:

r1 : ['acc', 'adc', 'aec', 'afc']
r2 : ['abc', 'ahc']

5. { }:

{n}:n 是一個非負整數。匹配確定的 n 次。
{n,}:n 是一個非負整數。至少匹配n 次。
{m,n}:m 和 n 均爲非負整數,其中n <= m。最少匹配 n 次且最多匹配 m 次。
示例代碼塊:

c = 'python 1111c00matLab098php'
r1 = re.findall('[A-Za-z]{3,5}', c)
r2 = re.findall('[A-Za-z]{3}', c)
r3 = re.findall('[A-Za-z]{3,}', c)
print(f'r1 : {r1}')
print(f'r2 : {r2}')
print(f'r3 : {r3}')

輸出結果:

r1 : ['pytho', 'matLa', 'php']
r2 : ['pyt', 'hon', 'mat', 'Lab', 'php']
r3 : ['python', 'matLab', 'php']

6. * 、+ 和 ?

*:匹配前面的子表達式零次或多次。
+:匹配前面的子表達式一次或多次。
?:匹配前面的子表達式零次或一次。
示例代碼塊:

a = 'pytho0python1pythonnn2'
r = re.findall('python*', a)
print(f'python* : {r}')

r = re.findall('python+', a)
print(f'python+ : {r}')

r = re.findall('python?', a)
print(f'python? : {r}')

r = re.findall('python{0,1}', a)
print('python{0,1} : '+ f'{r}')

r = re.findall('python{0,1}?', a)
print('python{0,1}? : '+ f'{r}')

r = re.findall('python{0,2}', a)
print('python{0,2} : '+ f'{r}')

r = re.findall('python{0,2}?', a)
print('python{0,2}? : '+ f'{r}')

輸出結果:

python* : ['pytho', 'python', 'pythonnn']
python+ : ['python', 'pythonnn']
python? : ['pytho', 'python', 'python']
python{0,1} : ['pytho', 'python', 'python']
python{0,1}? : ['pytho', 'pytho', 'pytho']
python{0,2} : ['pytho', 'python', 'pythonn']
python{0,2}? : ['pytho', 'pytho', 'pytho']

7. ^ 和 $

^:匹配輸入字符串的開始位置。
$:匹配輸入字符串的結束位置。
示例代碼塊:

qq1 = '123456789'
qq2 = '12345678'
qq3 = '1234'
qq4 = '123'

r1 = re.findall(r'^\d{4,8}$', qq1)
r2 = re.findall(r'^\d{4,8}$', qq2)
r3 = re.findall(r'^\d{4,8}$', qq3)
r4 = re.findall(r'^\d{4,8}$', qq4)

print('r1 : '+f'{r1}')
print('r2 : '+f'{r2}')
print('r3 : '+f'{r3}')
print('r4 : '+f'{r4}')

輸出結果:

r1 : []
r2 : ['12345678']
r3 : ['1234']
r4 : []

8. ()

(pattern):匹配 pattern 並獲取這一匹配。
示例代碼塊:

a = 'PythonPythonPythonPython'
r0 = re.findall('PythonPythonPython', a)
r1 = re.findall('(Python){3}', a)
r2 = re.findall('(Python){3}(Py){2}', a)
r3 = re.findall('(Python){3}Py', a)
r4 = re.findall('((Python){3}Py)', a)
r5 = re.findall('(Python)+', a)
print('r0 : ' + f'{r0}')
print('r1 : ' + f'{r1}')
print('r2 : ' + f'{r2}')
print('r3 : ' + f'{r3}')
print('r4 : ' + f'{r4}')
print('r5 : ' + f'{r5}')

輸出結果:

r0 : ['PythonPythonPython']
r1 : ['Python']
r2 : []
r3 : ['Python']
r4 : [('PythonPythonPythonPy', 'Python')]
r5 : ['Python']

9. re.I 和 re.S

re.I:不區分大小寫
re.S:匹配所有字符

示例代碼塊:

a = 'Python\nJava'
r1 = re.findall('python.{1}', a, re.I | re.S)
r2 = re.findall('python.+', a, re.I | re.S)
r3 = re.findall('python.', a, re.I | re.S)
r4 = re.findall('python?', a, re.I | re.S)
print(f'r1 : {r1}')
print(f'r2 : {r2}')
print(f'r3 : {r3}')
print(f'r4 : {r4}')

輸出結果:

r1 : ['Python\n']
r2 : ['Python\nJava']
r3 : ['Python\n']
r4 : ['Python']

10. re.sub():字符替換函數

示例代碼塊:

a = 'PythonC++JavaPHPC++'
b = 'PythonC++JavaPHPC++'
r1 = re.sub(r'C\+\+','C', a, 0)
r2 = re.sub(r'C\+\+','C', a, 1)
r3 = re.sub(r'C\+\+','C', b, 0)
r4 = b.replace('C++', 'C')
print(f'a : {a}')
print(f'r1 : {r1}')
print(f'r2 : {r2}')
print(f'r3 : {r3}')
print(f'r4 : {r4}')
print(f'b : {b}')

輸出結果:

a : PythonC++JavaPHPC++
r1 : PythonCJavaPHPC
r2 : PythonCJavaPHPC++
r3 : PythonCJavaPHPC
r4 : PythonCJavaPHPC
b : PythonC++JavaPHPC++

11. 方法作爲參數:

將方法名作爲替換函數的一個參數傳給re.sub()。這種將方法名作爲參數的形式在其他地方也經常遇見。

示例代碼塊:

def test11():
    # test methond as a parameter
    a = 'PythonCJava'
    r = re.sub('[Pp]ython', forTest11, a)

    print(f'r : {r}')

def forTest11(value):
    print(value)
    return '0'

輸出結果:

<re.Match object; span=(0, 6), match='Python'>
r : 0CJava

12. re.search() 和 re.match()

re.search():會在string內查找匹配,只要找到一個成功的匹配,就返回,若在整個string內都找不到匹配的,則返回None
re.match():只從字符串的開始位置匹配,即使是中間位置有匹配的項,也不算匹配成功,也就是說只有在開始位置匹配成功,纔有返回,若不是開始位置匹配成功,則返回None
示例代碼塊:

a = '8u9h33ko3uup'
r1 = re.search(r'\d', a)
r2 = re.match(r'\d', a)
r3 = re.findall(r'\d+', a)
print(f'r1.span() : {r1.span()}')
print(f'r2.group() : {r2.group()}')
print(f'r3 : {r3}')

輸出結果:

r1.span() : (0, 1)
r2.group() : 8
r3 : ['8', '9', '33', '3']

13. group() 和 groups()

group():要麼返回整個匹配對象,要麼根據要求返回特定子組;如果group()沒有子組要求,返回整個匹配。
groups():以元組的形勢返回所有匹配
示例代碼塊:

a = 'life is short, i love Python, I use python'
r1 = re.search('life(.*)python(.*)python', a, re.I)
r2 = re.findall('life(.*)python(.*)python', a, re.I)
print(f'group(0) : {r1.group(0)}')
print(f'group(1) : {r1.group(1)}')
print(f'group(2) : {r1.group(2)}')
print(f'group : {r1.group()}')
print(f'group(0,1,2) : {r1.group(0,1,2)}')
print(f'groups() : {r1.groups()}')
print(f'r2 : {r2}')
for i in range(len(r2)):
    print(f'i : {i}')
    for j in range(len(r2[i])):
        print(f'{i}{j} : {r2[i][j]}')

輸出結果:

group(0) : life is short, i love Python, I use python
group(1) :  is short, i love
group(2) : , I use
group : life is short, i love Python, I use python
group(0,1,2) : ('life is short, i love Python, I use python', ' is short, i love ', ', I use ')
groups() : (' is short, i love ', ', I use ')
r2 : [(' is short, i love ', ', I use ')]
i : 0
00 :  is short, i love
01 : , I use

總結:

正則表達式記不住,需要練習練習再練習。當然如果不是寫爬蟲,我倒是覺得需要時候先學一些基本的知識或者直接百度已經有的表達式就夠了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章