筆記_正則表示式_1
正則表示式
動機:
1.文字處理已經成為計算機常見的工作之一 2.對文字內容的搜尋,定位,提取 3.為了方便的解決上述問題,產生了正則表示式技術
定義:
即文字的高階匹配模式,提供搜尋,替換等功能。其本質是一系列由特殊符號組成的字串, 這個字串就是正則表示式(簡稱re)。
目標:
1.熟練掌握正則表示式符號 2.讀懂常見的正則表示式,編寫基本的搜尋提取功能正則 3.能夠熟練使用re模組操作正則表示式
正則表示式的特點
- 方便文字處理
- 支援的語言眾多
- 使用靈活變化
python --> re模組
re.findall(pattern, string)
功能: 提取所有的正則匹配內容
引數: pattern 正則表示式
string 目標字串
返回值: 列表,所有提取到的內容
元字元的使用
1.普通字元
元字元: a B c 匹配規則: 每個字元匹配對應的字元
In [4]: re.findall('ab','abchdgf')
Out[4]: ['ab']
2.或
元字元 : |
In [5]: re.findall('ab|ef','abchdgefgg')
Out[5]: ['ab', 'ef']
In [6]: re.findall('ab|bc','abcgggg')
Out[6]: ['ab'] #重疊的部分,取不出
In [7]: re.findall('ab | ef','abchdgefgg')
Out[ 7]: [] #空格也會被識別,不能隨意加空格
3.匹配單個字元
元字元: . 匹配規則: 匹配除換行外
In [8]: re.findall(‘f.o’,‘foo fao’) Out[8]: [‘foo’, ‘fao’]
In [9]: re.findall(‘f…d’,‘food fao’) Out[9]: [‘food’]
4.匹配字串開始位置
元字元: ^ 匹配規則:匹配字串的開始位置
In [13]: re.findall(’^Hello’,‘Hello Jay’) Out[13]: [‘Hello’]
In [14]: re.findall(’^Hello’,‘Jay Hello’) Out[14]: []
5.匹配字串開始位置
元字元: $ 匹配規則:匹配字串的結尾位置
In [16]: re.findall(‘Hello$’,‘Jay Hello’) Out[16]: [‘Hello’]
In [17]: re.findall(‘Hello$’,‘Jay Hello haha’) Out[17]: []
6.匹配重複
元字串: * 匹配規則: 匹配前面的字元重複 0 次或者多次 fo* 重複0次,> f fo* 重複多次,> fooo
In [18]: re.findall(‘fo*’,‘fooofaaaafoaaafoo’) Out[18]: [‘fooo’, ‘f’, ‘fo’, ‘foo’]
7.匹配重複
元字元: + 匹配規則: 匹配前面的字元重複1次或者多次 fo* 重複1次,> fo fo* 重複多次,> fooo
In [19]: re.findall(‘fo+’,‘fooofaaaafoaaafoo’) Out[19]: [‘fooo’, ‘fo’, ‘foo’]
8.匹配重複
字串: ? 匹配規則: 匹配前面的字元出現 0 次或 1 次
In [22]: re.findall(‘fo?’,‘fooooooaaafdddfo’) Out[22]: [‘fo’, ‘f’, ‘fo’]
9.匹配重複
元字元: {n} 匹配規則: 匹配前一個字元重複指定字數 fo{3} > fooo
In [24]: re.findall(‘fo{3}’,‘fooooooaaafdddfo’) Out[24]: [‘fooo’]
10.匹配重複
元字元: {m,n} 匹配規則: 匹配前面的字元出現 m–n 次 fo{2,4} > foo fooo foooo
In [25]: re.findall(‘fo{2,3}’,‘fooooooaaafoodddfo’) Out[25]: [‘fooo’, ‘foo’]
11.匹配字符集
字符集: [字符集] 匹配規則: 匹配字符集中的任意【一個】(不能連在一起)字元 [abc123] > 可匹配a b c 1 2 3 [a-zA-Z] > 可匹配從a到z,和A到Z之間的任意一個字元
匹配句子中以大寫字母開頭的單詞 In [26]: re.findall(’[A-Z]+[a-z]*’,‘This is my Jay’) Out[26]: [‘This’, ‘Jay’]
12.匹配字符集
字符集: [^…] 匹配規則: 匹配除了字符集中的任意一個字元一次或多次 [^abc] > 除了a/ b /c外的任意字元都可匹配
In [33]: re.findall(’[^ ]+’,‘This in my Jay’) #除空格外的… Out[33]: [‘This’, ‘in’, ‘my’, ‘Jay’] In [34]: re.findall(’[^0-9]+’,‘10+9-1=18’) #除數字外的… Out[34]: [’+’, ‘-’, ‘=’]
13.匹配任意(非)數字
元字元: \d \D 匹配規則: \d 匹配任意數字字元,[0-9] \D 匹配任意非數字字元,[^0-9]
In [35]: re.findall(‘1[\d]{10}’,‘18872075623 110112’) #匹配出1開頭的11位電話號碼… Out[35]: [‘18872075623’]
14.匹配任意(非)普通字元
元字元: \w \W 匹配規則: \w 匹配任意普通字元: [_0-9a-zA-Z]也能匹配漢字 \W 匹配任意非普通字元
In [36]: re.findall(’[\w]+’,‘my$zui-#aide–jay’) Out[36]: [‘my’, ‘zui’, ‘aide’, ‘jay’] In [37]: re.findall(’[\W]+’,‘my$zui-#aide–jay’) Out[37]: [’$’, ‘-#’, ‘–’]
15.匹配任意(非)空字元
元字元 : \s 匹配任意空字元 [\r\t\n\v\f] \S 匹配任意非空字元
In [38]: re.findall("\w+\s+\w+",“hello world”) Out[38]: [‘hello world’] In [39]: re.findall("\S+",“hello this is tom”) Out[39]: [‘hello’, ‘this’, ‘is’, ‘tom’]
16.匹配字串位置
元字元 : \A \Z 匹配規則: \A 匹配字串開頭位置 ,同 ^ \Z 匹配字串結尾位置 ,同 $
*絕對匹配 :
當正則表示式前有^(或\A),最後有$(或\Z)時,那麼這個正則表示式一定是要匹配目標字串的全部內容。否則就什麼都不匹配。
In [38]: re.findall("\A\d+\Z",“123445”) Out[38]: [‘123445’] In [39]: re.findall("\A\d+\Z","123445 ") Out[39]: []
17.匹配(非)單詞邊界
元字元 : \b \B 匹配規則 : \b 匹配單詞邊界位置 (普通字元和非普通字元交界認為是單詞邊界) \B 匹配非單詞邊界位置
In [40]: re.findall(r"\bis\b",“this is Jay”) Out[40]: [‘is’]
元字元總結
匹配單個字元: . […] [^…] \d \D \w \W \s \S 匹配重複: * + ? {n} {m,n} 匹配位置: ^ $ \A \Z \b \B 其他 : | () \
正則表示式轉義
正則中的特殊符號:. * + ? ^ $ [] {} () | \
在正則表示式中,如果匹配特殊字元需要加 \ 作為轉義
eg.: 匹配. 需要使用.
python字串 正則 目標字串
'\\$\\d+' \$\d+ $10
raw字串 : 不對字串內容進行轉義處理
'\\$\\d+' ==> r'\$\d+'
貪婪與非貪婪
-
貪婪模式: 正則表示式的重複匹配預設總是儘可能的向後匹配更多的內容。
* + ? {m,n}
-
非貪婪(懶惰)模式 : 儘可能少地匹配重複內容。
貪婪 -->> 非貪婪 *? +? ?? {m,n}?
In [41]: re.findall(r"ab+?",“abbbbbbbb”) Out[41]: [‘ab’]
In [42]: re.findall(r"ab??",“abbbbbbbb”) Out[42]: [‘a’]
正則表示式的分組
使用()為正則表示式建立內部分組(子組),子組為正則表示式的一部分,可以看做一個內部整體。 有子組的正則表示式仍然是整體去匹配內容,子組需要在整體能夠匹配到內容的前提下發揮作用。
子組的作用:
1.作為內部整體可以改變某些元字元的行為。
In [3]: re.search(r"(ab)+\d+",“ababab1234”).group( ) Out[3]: ‘ababab1234’ In [4]: re.search(r"\[email protected]\w+.cn|com",“[email protected]”).group( ) Out[4]: ‘com’ In [5]: re.search(r"\[email protected]\w+.(cn|com)",“[email protected]”).group( ) Out[5]: ‘[email protected]’
2.子組在匹配到內容的情況下,可以單獨提取出匹配內容。
In [7]: re.search(r"(https|http|ftp)?/\S+",“https://www.baidu.com”).group(1) Out[7]: ‘https’
子組使用的注意事項:
- 一個正則表示式中可以有多個子組
- 子組一般由外到內,由左到右稱之為第一,第二,第三…子組
- 子組不能重疊或者巢狀過多
捕獲組和非捕獲組
格式: (?P<name>pattern)
In [8]: re.search(r"(?P<dog>ab)cdef",'abcdefghi').group('dog')
Out[8]: ‘ab’ #給子組命名dog,利用名字獲取子組內容
正則表示式的設計原則:
- 正確性:能正確匹配到目標內容
- 排他性:除了要匹配的內容,儘可能不會匹配與到其他內容
- 全面型:儘可能對目標字串各自情況進行考慮,做到不遺漏
re模組
regex = compile(pattern, flags = 0)
- 功能 : 生成正則表示式物件
- 引數 : pattern 正則表示式 flags 功能標誌位,豐富正則表示式的匹配功能
- 返回值 : 返回正則表示式物件
re.findall(pattern, string, flags = 0)
- 功能 :從目標字串查詢正則匹配內容
- 引數 :pattern 正則表示式 string 目標字串 flags 標誌位
- 返回值 : 返回匹配到的內容(如果正則有子組,則只返回子組對應內容!!)
regex.findall(string, pos, endpos)
- 功能 :從目標字串查詢所有正則匹配內容
- 引數 :string 目標字串 pos 擷取目標字串的起始位置 endpos 擷取目標字串的終止位置
- 返回值 :返回匹配到的內容列表,如果正則有子組則只返回子組中的內容
@import “./code/regex.py”
import re
pattern = r"(\w+):(\d+)"
s = "zhang:1994 li:1993"
#re直接呼叫
l = re.findall(pattern,s,flags = 0)
print(l) # [('zhang', '1994'), ('li', '1993')]
#compile物件呼叫
regex = re.compile(pattern,flags = 0)
l = regex.findall(s,pos=0,endpos=12)
print(l) # [('zhang', '1994')]
re.split(pattern, string, flags)
- 功能 :從目標字串查詢所有正則匹配內容
- 引數 :pattern 正則表示式 string 目標字串 flags 標誌位
- 返回值 :返回匹配到的內容列表,如果正則有子組則只返回子組中的內容
例如:./code/re_split.py
#示意re模組的split的用法
import re
l = re.split(r'\s+','hello world nihao beijing',flags = 0)
print(l) #['hello', 'world', 'nihao', 'beijing']
re.sub(pattern, replaceStr, string, max, flags)
- 功能:使用字串替換正則匹配的內容
- 引數:pattern 正則表示式 replaceStr 替換的字串 string 目標字串 max 最多替換幾處,預設全部替換 flags 標誌位
- 返回值:返回替換後的字串
例如:./code/re_sub.py
re.subn(pattern, replaceStr, string, max, flags)
- 功能:使用字串替換正則匹配的內容
- 引數:pattern:正則表示式 replaceStr:替換的字串 string:目標字串 max:最多替換幾處,預設全部替換 flags 標誌位
- 返回值:返回替換後的字串 和 替換了幾處
例如:/code/re_sub.py
#示意re模組的sub / sunb的用法
import re
s = re.sub(r'\s+','**','hello world nihao beijing')
print(s) # hello**world**nihao**beijing
s = re.sub(r'\s+','**','hello world nihao beijing',2)
print(s) # hello**world**nihao beijing
s = re.subn(r'\s+','**','hello world nihao beijing',2)
print(s) # ('hello**world**nihao beijing', 2)
re.finditer(pattern, string)
- 功能: 使用正則表示式匹配目標字串
- 引數: pattern 正則表示式 string 目標字串
- 返回值: 返回一個迭代物件,迭代到的內容是一個match物件
fullmatch(pattern,string,flags)
- 功能: 絕對匹配目標字串
- 引數: pattern 正則 string 目標字串
- 返回值:match物件
例:@import “./code/regex1.py”
match(pattern, string, flags)
- 功能: 從開頭位置匹配目標字串
- 引數: pattern 正則 string 目標字串 flags
- 返回值:返回匹配到的match物件,如果沒匹配成功返回None
例:@import “./code/regex1.py”
search(pattern, string, flags)
- 功能: 正則表示式匹配目標字串,只匹配第一處!!
- 引數: pattern, string, flags
- 返回值:返回匹配到的match物件,如果沒匹配成功返回None
例:@import “./code/regex1.py”
import re
pattern = r'\d+'
s = "2008年事情多,08奧運,512地震"
it = re.finditer(pattern,s)
# print(dir(next(it)))
for i in it:
#match物件group函式獲取匹配內容
print(i.group()) # 2008 08 512
try:
obj = re.fullmatch(r'\w+','hello1973')
print(obj.group()) # hello1973
except AttributeError as e:
print(e)
obj = re.match(r'[A-Z]\w+',"Hello World")
print(obj.group()) # Hello
obj = re.search(r'\d+',s)
print(obj.group()) # 2008
regex 物件屬性:
pattern:
In [9]: regex = re.compile(r'abcdef')
In [10]: regex.pattern
Out[10]: 'abcdef'
flags: 表示標誌位常亮值
group: 表示正則有多少個子組
groupindex: 生成(捕獲組名和對應第幾組)的鍵值對,構成的字典 #
作業:
- 熟記正則表示式元字元
- 找一個文件,使用正則表示式:
- 匹配其中的大寫子母開頭的單詞
- 匹配其中所有的數字(整數,浮點數,負數,百分數,分數…)
- 複習:regex物件呼叫函式