Python3 正則表達式

Python3 正則表達式

  • 正則表達式是一個特殊的字符序列,它能幫助我們方便的檢查一個字符串是否與某種模式匹配。
  • 模式字符串使用特殊的語法來表示一個正則表達式
  • 下面列出了正則表達式模式語法中的特殊元素
模 式 含義
^ 匹配字符串的開頭
$ 匹配字符串的末尾。
. 匹配任意字符,除了換行符,當re.DOTALL標記被指定時,則可以匹配包括換行符的任意字符。
[...] 用來表示一組字符,單獨列出:[amk] 匹配 'a','m'或'k'
[^...] 不在[]中的字符:[^abc] 匹配除了a,b,c之外的字符。
re* 匹配0個或多個的表達式。
re+ 匹配1個或多個的表達式。
re? 匹配0個或1個由前面的正則表達式定義的片段,非貪婪方式
re{ n} 精確匹配 n 個前面表達式。例如, o{2} 不能匹配 "Bob" 中的 "o",但是能匹配 "food" 中的兩個 o。
re{ n,} 匹配 n 個前面表達式。例如, o{2,} 不能匹配"Bob"中的"o",但能匹配 "foooood"中的所有 o。"o{1,}" 等價於 "o+"。"o{0,}" 則等價於 "o*"。
re{ n, m} 匹配 n 到 m 次由前面的正則表達式定義的片段,貪婪方式
a|b 匹配a或b\n
(re) 匹配括號內的表達式,也表示一個組
(?imx) 正則表達式包含三種可選標誌:i, m, 或 x 。隻影響括號中的區域。
(?-imx) 正則表達式關閉 i, m, 或 x 可選標誌。隻影響括號中的區域。
(?: re) 類似 (...), 但是不表示一個組
(?imx: re) 在括號中使用i, m, 或 x 可選標誌
(?-imx: re) 在括號中不使用i, m, 或 x 可選標誌
(?#...) 註釋.
(?= re) 前向肯定界定符。如果所含正則表達式,以 ... 表示,在當前位置成功匹配時成功,否則失敗。但一旦所含表達式已經嘗試,匹配引擎根本沒有提高;模式的剩餘部分還要嘗試界定符的右邊。
(?! re) 前向否定界定符。與肯定界定符相反;當所含表達式不能在字符串當前位置匹配時成功
(?> re) 匹配的獨立模式,省去回溯。
\w 匹配字母數字及下
\W 匹配非字母數字及下劃線
\s 匹配任意空白字符,等價於 [\t\n\r\f].
\S 匹配任意非空字符
\d 匹配任意數字,等價於 [0-9].
\D 匹配任意非數字
\A 匹配字符串開始
\Z 匹配字符串結束,如果是存在換行,只匹配到換行前的結束字符串。
\z 匹配字符串結束
\G 匹配最後匹配完成的位置。
\b 匹配一個單詞邊界,也就是指單詞和空格間的位置。例如, 'er\b' 可以匹配"never" 中的 'er',但不能匹配 "verb" 中的 'er'。
\B 匹配非單詞邊界。'er\B' 能匹配 "verb" 中的 'er',但不能匹配 "never" 中的 'er'。
\n, \t, 等. 匹配一個換行符。匹配一個製表符。等
\1...\9 匹配第n個分組的內容。
\10 匹配第n個分組的內容,如果它經匹配。否則指的是八進制字符碼的表達式。

match()和search()的區別

  • match() 方法只從開始找,開始第一個字符不匹配就找不到了,返回none
  • search()查找整個字符串,找到第一個爲止
    示例代碼1:
#!/usr/bin/python3

import re

# 使用 match對象  
match = re.match('yhyang','aayhyang正在學習正則表達式')
print(match)     # 最開始匹配不到返回none
輸出:
None

match = re.search('yhyang','aayhyang正在學習正則表達式')
print(match.group())  # 直到找到匹配的字符串
輸出:
yhyang

示例代碼2:

#!/usr/bin/python3

import re

import re
s = """
1234-1234-113
133-1234-2123
125-4567-3456
[email protected]
[email protected]
[email protected]
http://baidu.com
https://github.com
http://taobao.com
"""
target = '\d{4}'                 # \d 匹配數字 {4} 表示4個  代表找到4個數字
target = '\d{4}-\d{4}-\d{3}'
target = '\d{3}-\d{4}-\d{4}'
target = '\d+-\d+-\d+'         #  \d匹配數字,+ 表示1個或多個,search 找到第一個就停下來了
target = '[\d+-?]+'           # ? 表示後面跟0個或多個   [] 表示一個字符集如:[a-z]查找小寫字母
target = '\w{5}@\w{2}.com'    #  \w 匹配字符
match = re.search(target,s)
if match:
    print('找到,',target,s)
    print(match.group())
else:
    print('啥都沒找到')

輸出:
找到, \w{5}@\w{2}.com 
1234-1234-113
133-1234-2123
125-4567-3456
[email protected]
[email protected]
[email protected]
http://baidu.com
https://github.com
http://taobao.com

[email protected]

分組

  • () 括號分組
  • | 管道符號匹配多個分組
  • ?選擇出現0次或1次
  • re.x 換行,註釋
  • findall
    • 有分組,返回元組列表
    • 無分組,返回字符串列表
  • split
    • 返回用正則分割後的列表

compile 函數

compile 函數用於編譯正則表達式,生成一個正則表達式( Pattern )對象,供 match() 和 search() 這兩個函數使用。
語法格式爲:
re.compile(pattern[, flags])<br/>
參數:

pattern : 一個字符串形式的正則表達式
flags 可選,表示匹配模式,比如忽略大小寫,多行模式等,具體參數爲:
    re.I 忽略大小寫
    re.L 表示特殊字符集 \w, \W, \b, \B, \s, \S 依賴於當前環境
    re.M 多行模式
    re.S 即爲' . '並且包括換行符在內的任意字符(' . '不包括換行符)
    re.U 表示特殊字符集 \w, \W, \b, \B, \d, \D, \s, \S 依賴於 Unicode 字符屬性數據庫
    re.X 爲了增加可讀性,忽略空格和' # '後面的註釋

示例代碼1:

#!/usr/bin/python3

import re

regex = re.compile(r'yhyang')  # r 表示raw 原始的
regex.findall('asdfasdfasfyhyang,235346747,yhyang')

輸出:
['yhyang', 'yhyang']

示例代碼2:

#!/usr/bin/python3

import re

regex = re.compile(r'(yhyang)')         # ()  分割,分組
regex.split('asdfasdfasfyhyang,235346747,yhyang')

輸出:
['asdfasdfasf', 'yhyang', ',235346747,', 'yhyang', '']

匹配IP地址

#!/usr/bin/python3
import re

parten = ((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  匹配 24x  x爲0-9
# 25[0-5]  匹配 25x  x爲0-5
# [01]?\d\d?  [01]? 匹配0個或是一個0或1,\d? 表示0個或1個數字
# \.  轉義 . 
# {3} 前面的規則匹配3次

# 注意命名 re開頭
re_ip = re.compile(r'((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)')
match = re_ip.match('1.2.3.4')
print(match)
print(match.group())

輸出:
<_sre.SRE_Match object; span=(0, 7), match='1.2.3.4'>
1.2.3.4
示例代碼2:

#!/usr/bin/python3

import re

re_ip = re.compile(r'''
    ((2[0-4]\d|25[0-5]|[01]?\d\d?)\.)  # IP表示一組數字包括後邊的點
    {3}                                # 表示3組數字
    (2[0-4]\d|25[0-5]|[01]?\d\d?)      # 最後一組數字
    ''',re.X)                          # 正則可以換行,註釋
match = re_ip.match('192.168.3.4')
print(match)
print(match.group())

輸出:
<_sre.SRE_Match object; span=(0, 11), match='192.168.3.4'>
192.168.3.4

匹配要不要貪心一點

模式 含義 示例
{m,n}? 對於前一個字符重複m到n次,並取儘可能少的情況 在字符串‘aaaaaa’中,a{2,4}會匹配4個a,但a{2,4}?只會匹配2個a
.*與?的搭配 默認貪心,有多少要多少,?給加上限制,表示非貪心匹配,?把*匹配的字符限制到最少 r'"(.)"'與 r'"(.?)"'
  • *?重複任意次,但儘可能少重複
  • +?重複1次或多次,但儘可能少重複
  • ??重複0次或1次,但儘可能少重複
  • {n,}?重複n次以上,但儘可能少重複
    示例代碼1:
#!/usr/bin/python3

import re

# 只匹配雙引號中的內容,包括雙引號
re_quote = re.compile(r'"(.*)"')
text1 = 'Computer says "no"'
find1 = re_quote.findall(text1)
print(find1)
text2 = 'Computer says "no" Phone says "yes"'
find2 = re_quote.findall(text2)
print(find2)

輸出:
['no']
['no" Phone says "yes']

示例代碼2:

#!/usr/bin/python3

import re

re_quote = re.compile(r'"(.*?)"')
text1 = 'Computer says "no"'
find1 = re_quote.findall(text1)
print(find1)
text2 = 'Computer says "no" Phone says "yes"'
find2 = re_quote.findall(text2)
print(find2)

輸出:
['no']
['no', 'yes']

正則替換

示例代碼:

#!/usr/bin/python3

import re

s = 'sadfasfasdfasdfyhyangdsafasf2352'
ss = s.replace('yhyang','******')   # 替換
print(ss)

regex = re.compile(r'yhyang') # 生成規則對象
regex.sub('******',s)   # 替換

輸出:
sadfasfasdfasdf**dsafasf2352
'sadfasfasdfasdf**dsafasf2352'

下邊例子分組標號\1,\2,\3 類似於awk的列分組 $1 ……

示例代碼1:

#!/usr/bin/python3

import re

# 通過分組替換字符串格式,mm/dd/yy  -> yy-mm-dd
s = '替換日期格式:10/01/2018,12/25/2018'
re_date = re.compile(r'(\d+)/(\d+)/(\d+)')  # 此處給(\d+)/(\d+)/(\d+)按/分爲三組,標號爲\1,\2,\3
re_date.sub(r'\3-\1-\2',s)   # 將上邊的\1,\2,\3位置按要求重新排列

輸出:
'替換日期格式:2018-10-01,2018-12-25'
示例代碼2:

#!/usr/bin/python3

import re

# 替換字符串中間的多餘空格
s = '      yhyang    正則   python  好難學, 堅持一下吧, 沒 幾  個了'
s.strip()  # 只去掉最前邊的
re_blank = re.compile(r'\s+') # \s 代表空格
re_blank.sub('',s)

輸出:
'yhyang正則python好難學,堅持一下吧,沒幾個了'

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