標籤:並且 提取 添加 基礎 cas number service mat find
Regex 為進階的文字模式匹配、抽取、與/或文本形式的搜尋和替換功能提供了基礎。簡單地說,Regex(簡稱為 regex)是一些由字元和特殊符號組成的字串,它們描述了模式的重複或者表述多個字元,於是Regex能按照某種模式比對一系列有相似特徵的字串。換句話說,它們能夠匹配多個字串……一種只能匹配一個字串的Regex模式是很乏味並且毫無作用的,不是嗎?Python 通過標準庫中的 re 模組來支援Regex
Regex的特殊字元列表
‘.‘ 匹配所有字串,除\n以外
‘-’ 表示範圍[0-9]
‘*‘ 匹配前面的子運算式零次或多次。要匹配 * 字元,請使用 \*。
‘+‘ 匹配前面的子運算式一次或多次。要匹配 + 字元,請使用 \+
‘^‘ 匹配字串開頭
‘$’ 匹配字串結尾 re
‘‘ 逸出字元, 使後一個字元改變原來的意思,如果字串中有字元*需要匹配,可以\*
‘?’ 匹配前一個字串0次或1次
‘{m}‘ 匹配前一個字元m次
‘{n,m}‘ 匹配前一個字元n到m次
‘\d‘ 匹配數字,等於[0-9]
‘\D‘ 匹配非數字,等於[^0-9]
‘\w‘ 匹配字母和數字,等於[A-Za-z0-9]
‘\W‘ 匹配非英文字母和數字,等於[^A-Za-z0-9]
‘\s‘ 匹配空白字元
‘\S‘ 匹配非空白字元
‘\A‘ 匹配字串開頭
‘\Z‘ 匹配字串結尾
‘\b‘ 匹配單詞的詞首和詞尾,單詞被定義為一個字母數字序列,因此詞尾是用空白符或非字母數字元來表示的
‘\B‘ 與\b相反,只在當前位置不在單詞邊界時匹配
‘(?P 分組,除了原有編號外在指定一個額外的別名
[] 是定義匹配的字元範圍。比如 [a-zA-Z0-9] 表示相應位置的字元要匹配英文字元和數字。[\s*]表示空格或者*號。
Python的reRegex模組提供的方法
re.match(pattern, string, flags=0) #從字串的起始位置匹配,如果起始位置匹配不成功的話,match()就返回nonere.search(pattern, string, flags=0) #掃描整個字串並返回第一個成功的匹配re.findall(pattern, string, flags=0) #找到RE匹配的所有字串,並把他們作為一個列表返回re.finditer(pattern, string, flags=0) #找到RE匹配的所有字串,並把他們作為一個迭代器返回re.sub(pattern, repl, string, count=0, flags=0) #替換匹配到的字串
函數參數說明:
pattern: 匹配的Regex string:要匹配的字串
flags: 標記為,用於控制Regex的匹配方式,如:是否區分大小寫,多行匹配等等。
repl: 替換的字串,也可作為一個函數
count: 模式比對後替換的最大次數,預設0表示替換所有匹配
import rem = re.match(r‘f..‘, r‘begin fool hello‘) # match 從字串的開始位置進行搜尋,如果需從字串任意位置進行搜尋,需使用下文中的search方法if m is not None: print(‘found : ‘ + m.group())else: print(‘not found!‘)
not found!
search()函數不但會搜尋模式在字串中第一次出現的位置,而且嚴格地對字串從左至右搜尋。
m = re.search(r‘foo‘, ‘beginfool hello‘)if m is not None: print(‘found : ‘ + m.group())else: print(‘not found...‘)
found : foo
匹配任何單個字串
anyend = ‘.end‘m = re.match(anyend, ‘bend‘) # 點號匹配‘b’if m is not None: print(m.group())
bend
m = re.match(anyend, ‘end‘) # 不匹配任何字串if m is not None: print(m.group())
m = re.match(anyend, ‘\nbend‘) # 除了‘\n‘之外的任何字串if m is not None: print(m.group())
m = re.match(anyend, ‘The end.‘) # 點號匹配‘ end’if m is not None: print(m.group())
gorup()和groups()方法的使用
m = re.match(r‘(\w{3})-(\d{3})‘, ‘abc-123‘)if m is not None: print(‘m.group(): ‘ + m.group()) print(‘m.group(1): ‘ + m.group(1)) print(‘m.group(2): ‘ + m.group(2)) print(‘m.groups(): ‘ + str(m.groups()))
m.group(): abc-123m.group(1): abcm.group(2): 123m.groups(): (‘abc‘, ‘123‘)
findall()查詢字串中某個Regex模式全部的非重複出現情況。這與 search()在執行字串搜尋時類似,但與 match()和 search()的不同之處在於,findall()總是返回一個列表。如果 findall()沒有找到匹配的部分,就返回一個空列表,但如果匹配成功,列表將包含所有成功的匹配部分(從左向右按出現順序排列)。
re.findall(‘car‘, ‘car‘)
[‘car‘]
re.findall(‘car‘, ‘scary‘)
[‘car‘]
re.findall(‘car‘, ‘carry the brcardi to the car‘)
[‘car‘, ‘car‘, ‘car‘]
finditer()和findall()返回的匹配字串相比,finditer()在匹配對象中迭代.
s = ‘This and that.‘re.findall(r‘(th\w+)‘, s, re.I)
[‘This‘, ‘that‘]
iter = re.finditer(r‘(th\w+)‘, s, re.I)iter
<callable_iterator at 0x594a780>
[g.group() for g in iter] # findall 返回一個列表,而finditer返回一個迭代器
[]
有兩個函數/方法用於實現搜尋和替換功能:sub()和 subn()。兩者幾乎一樣,都是將某字串中所有匹配Regex的部分進行某種形式的替換。用來替換的部分通常是一個字串,但它也可能是一個函數,該函數返回一個用來替換的字串。subn()和 sub()一樣,但 subn()還返回一個表示替換的總數,替換後的字串和表示替換總數的數字一起作為一個擁有兩個元素的元組返回。
print(re.sub(‘X‘, ‘Mr. Iceman‘, ‘attn: X\n\nDear X,\n‘))
attn: Mr. Iceman Dear Mr. Iceman,
print(re.subn(‘X‘, ‘Mr. Iceman‘, ‘attn: X\n\nDear X,\n‘))
(‘attn: Mr. Iceman\n\nDear Mr. Iceman,\n‘, 2)
re 模組和Regex的對象方法 split()對於相對應字串的工作方式是類似的,但是與分割一個固定字串相比,它們基於Regex的模式分隔字串,為字串分隔功能添加一些額外的威力。
如果給定分隔字元不是使用特殊符號來匹配多重模式的Regex,那麼 re.split()與str.split()的工作方式相同
re.split(‘:‘, ‘str1:str2:str3‘)
[‘str1‘, ‘str2‘, ‘str3‘]
DATA = ( ‘Mountain View, CA 94040‘, ‘Sunnyvale, CA‘, ‘Los Altos, 94023‘, ‘Cupertino 95014‘, ‘Palo Alto CA‘)for item in DATA: print( re.split(‘, |(?= (?:\d{5}|[A-Z]{2})) ‘, item))
[‘Mountain View‘, ‘CA‘, ‘94040‘][‘Sunnyvale‘, ‘CA‘][‘Los Altos‘, ‘94023‘][‘Cupertino‘, ‘95014‘][‘Palo Alto‘, ‘CA‘]
import osimport rewith os.popen(‘tasklist /nh‘, ‘r‘) as f: for line in list(f)[:5]: # print(re.split(r‘\s\s+|\t‘, line.rstrip())) #pid 和會話名未分解 print(re.findall(r‘([\w.]+(?: [\w.]+)*)\s\s*(\d+)\s(\w+)\s\s*(\d+)\s\s*([\d,]+\sK)‘, line.strip()))
[][(‘System Idle Process‘, ‘0‘, ‘Services‘, ‘0‘, ‘24 K‘)][(‘System‘, ‘4‘, ‘Services‘, ‘0‘, ‘2,852 K‘)][(‘smss.exe‘, ‘364‘, ‘Services‘, ‘0‘, ‘1,268 K‘)][(‘csrss.exe‘, ‘612‘, ‘Services‘, ‘0‘, ‘6,648 K‘)]
如下以一完整樣本結束本文,它以不同的方式使用Regex來操作字串。首先使用該指令碼為Regex練習建立隨機資料,然後將產生的資料提取其中的數字和郵箱地址
from random import randrange, choicefrom string import ascii_lowercase as lcfrom datetime import datetimeimport timeimport reresult_data = []# gen datatlds = (‘com‘, ‘cn‘, ‘edu‘, ‘net‘, ‘gov‘, ‘org‘)for i in range(randrange(4, 9)): max_seconds = int(datetime.now().timestamp()) dtint = randrange(max_seconds) #dtstr = str(datetime.fromtimestamp(dtint)) dtstr = ctime(dtint) llen = randrange(4, 8) login = ‘‘.join(choice(lc) for j in range(llen)) dlen = randrange(llen, 13) dom = ‘‘.join(choice(lc) for j in range(dlen)) result_data.append(‘%s::%s@%s.%s::%d-%d-%d‘ % (dtstr, login, dom, choice(tlds), dtint, llen, dlen))#print(result_data)#test rere_patt = ‘^(\w{3}).*::(?P<email>\[email protected]\w+.\w+)::(?P<number>\d+-\d+-\d+)‘for item in result_data: m = re.match(re_patt, item) if m is not None: print(‘*‘*30) print(item) print("Email: " + m.group(‘email‘)) print(‘Number: ‘ + m.group(‘number‘))
******************************Tue Jan 28 15:34:09 1992::[email protected]::696584049-7-11Email: [email protected]Number: 696584049-7-11******************************Thu Dec 23 22:35:52 1971::[email protected]::62346952-6-7Email: [email protected]Number: 62346952-6-7******************************Sat Jan 25 11:26:50 2003::[email protected]::1043465210-6-8Email: [email protected]Number: 1043465210-6-8******************************Wed Sep 28 23:37:34 1977::[email protected]::244309054-7-10Email: [email protected]Number: 244309054-7-10******************************Sun Feb 7 12:08:11 1988::[email protected]::571205291-4-9Email: [email protected]Number: 571205291-4-9******************************Sat Aug 31 00:04:58 1996::[email protected]::841421098-4-8Email: [email protected]Number: 841421098-4-8******************************Tue Oct 9 05:32:20 1984::[email protected]::466119140-7-7Email: [email protected]Number: 466119140-7-7
Python資料分析學習-reRegex模組