正则表达式
-
处理对象:字符串,python中使用re模块
-
语法规则
* 匹配0次或多次 + 匹配1次或多次 ? 匹配0次或1次 \ 转义字符,使字符改变原来的意思 ^ 匹配字符串开头 $ 匹配字符串结尾 | 或,匹配|左右表达式任意一个,从左到右匹配,如果|没有包括在()中,则它的范围是整个正则表达式 {} {m}匹配前一个字符m次,{m,n}匹配前一个字符m至n次,{m,}匹配m至无限次 [] 字符集,多选一,对应的位置可以是字符集中任意字符分组表达式作为一个整体,可以后接数量词。 [a-z]从a到c [0-9] 0-9的数字 [09-] 0、9、-三个字符 [0\-9] 0、9、-三个字符 () 被括起来的表达式将作为分组,从表达式左边开始没遇到一个分组的左括号“(”,编号+1。分组表达式作为一个整体,可以后接数量词。表达式中的|仅在该组中有效。
-
预定义字符集
\d 数字[0-9] \D 非数字[^\d] \s 匹配任何空白字符[<空格>\t\r\n\f\v] \S 非空白字符[^\s] \w 匹配包括下划线在内的任何字字符[A-Z a-z 0-9 _] \W 匹配非字母字符,即匹配特殊字符 \A 仅匹配字符串开头,同 ^ \Z 仅匹配字符串结尾,同 $ \b 匹配\w和\W之间,即匹配单词边界匹配一个单词边界,也就是指单词和空格间的位置 \B [^\b] . 匹配除换行符 \n 外的字符
-
特殊分组用法
(?P<name>str) 分组,除了原有的编号外再指定一个额外的别名 (?P<id>abc){2} abcabc (?P=name) 引用别名为<name>的分组匹配到字符串 (?P<id>\d)abc(?P=id) 1abc1 5abc5 \<number> 引用编号为<number>的分组匹配到字符串 (\d)abc\1 1abc1 5abc5
-
例子
-
字符 \d 的理解
import re regex = re.compile(r'\d+') s = 'abc123adawae12edqwe657' res = re.findall(regex, s) print(res) # ['123', '12', '657']
-
字符 \b 的理解
import re regex1 = r'\btina' res1 = re.findall(regex1, 'tiantinaaaa') print(res1) # [] regex2 = r'\btina' res2 = re.findall(regex2 ,'tian tinaaaa') print(res2) # ['tina'] regex3 = r'\btina' res3 = re.findall(regex3, 'tian#tinaaaa') print(res3) # ['tina'] regex4 = r'\btina\b' res4 = re.findall(regex4, 'tian#tina@aaa') print(res4) # ['tina']
-
字符集[]的理解
import re name = '李小明' regex = re.compile(r'李[二小]明') res = re.match(regex, name) print(res) # <re.Match object; span=(0, 3), match='李小明'>
-
或|的理解
import re name = '李小明' regex2 = r'李(二|小)明' res = re.match(regex2, name) print(res) # <re.Match object; span=(0, 3), match='李小明'>,若去掉(),为None
-
字符\s的理解
import re s=''' <name id="001"> tom </name> <age>12</age> <name>jack</name> <name id='002'>rose</name> ''' regex5 =r'<name id=.+>\s*(\w+)\s*</name>' res5 = re.findall(regex5, s) print(res5) # ['tom', 'rose']
-
匹配电话号3/4位(0+2/3位)+(7/8位)
import re s6 = '0112-12345678' regex6 = re.compile(r'0\d{2,3}-\d{7,8}') res6 = re.match(regex6, s6) print(res6) # <re.Match object; span=(0, 13), match='0112-12345678'>
-
匹配邮箱 字符@字符.2/3.2/3
import re s7 = '11368218@qq.com' regex7 = re.compile(r'\w+@\w+(\.\w{2,3}){1,2}') res7 = re.match(regex7, s7) print(res7) # <re.Match object; span=(0, 15), match='11368218@qq.com'>
-
不获取?:的使用
# 当不加括号(),全部都要--findall # ()分组,只保留括号内的--findall # (?: ) 当表示分隔符,不是分组内容,即不获取,则加上 ?: import re # regex8 = re.compile(r'\w+@\w+(\.\w{2,3}){1,2}') regex8 = re.compile(r'(\w+@\w+(?:\.\w{2,3}){1,2})') s8 = 'abac@163.com.cn fdkfjd lzhan@qq.com,fdkjfkdfjdk,aaa@qq.cjom' res8 = re.findall(regex8,s8) print(res8) # ['abac@163.com.cn', 'lzhan@qq.com', 'aaa@qq.cjo']
-
对 ^ $ 的理解
regex9 = re.compile(r'^李\w{1,2}$') # regex9 = re.compile(r'李\w{1,2}') #如果不加上开始和结束标志,其实就是匹配部分数据,下面的字符串就会匹配'李小飞' s9 = '李小飞龙' res9 = re.findall(regex9, s9) print(res9) # []
-
查找不存在某字符串的
s1 = '123dsifd' s2 = '123abc2312' import re regex = r'(?!.*abc).*' res1 = re.match(regex, s1) print(res1) # <re.Match object; span=(0, 8), match='123dsifd'> res2 = re.match(regex, s2) print(res2) # None
-
-
完全匹配
^\w{3}\w{3}$ 完全匹配 整个字符与整个规则进行匹配--与match结合用
-
规律匹配
-
匹配abcabc类型
print('【匹配abcabc类型】:') import re s1='abcabc' s2='abcdef' reg01 = r'^(?P<fir>\w+)(?P=fir)$' res1 = re.match(reg01, s1) res2 = re.match(reg01, s2) print(res1) # <re.Match object; span=(0, 6), match='abcabc'> print(res2) # None
-
-
re模块中常用的功能函数
-
compile():将正则表达式编译成Python识别的语句
import re s1='abcabc' s2='abcdef' reg01 = r'^(?P<fir>\w+)(?P=fir)$' regex = re.compile(reg01) res1 = re.match(regex, s1) res2 = re.match(regex, s2) print(res1) # <re.Match object; span=(0, 6), match='abcabc'> print(res2) # None
flags = re.I 忽视大小写
flags = re.S 使.匹配包括换行在内的所有字符
flags = re.L 做本地化识别(locale-aware)匹配,法语等
flags = re.M 多行匹配,影响^和$
flags = re.X 通过给予更灵活的格式以便将正则表达式写得更易于理解
flags = re.U 根据Unicode字符集解析字符,这个标志影响\w,\W,\b,\Bimport re s = 'abc ABC' regex = re.compile(r'abc', flags=re.I) res = re.findall(regex, s) print(res) # ['abc', 'ABC']
-
match():匹配,不是完全匹配
决定re是否在字符串刚开始的位置匹配。//注:这个方法并不是完全匹配。
当pattern结束时若string还有剩余字符,
仍然视为成功。想要完全匹配,可以在表达式末尾加上边界匹配符’$’
没有()就是匹配模式,匹配模式就是从开始第一个字符进行匹配,如果匹配成功,那么后面的内容就不会匹配。
有了()就是分组查找模式,有了分组就是把匹配到的内容分组存放
-
search():查找,在字符串内查找模式匹配,只要找到第一个匹配然后返回,如果字符串没有匹配,则返回None。
-
findall():遍历匹配,可以获取字符串中所有匹配的字符串,返回一个列表。
import re s = 'abc 中国 Anb 深圳 dsjkfjk 日本asf' regex = re.compile(r'[\u4E00-\u9FA5]+') res = re.findall(regex, s) print(res) # ['中国', '深圳', '日本']
-
finditer(): 搜索string,返回一个顺序访问每一个匹配结果(Match对象)的迭代器
找到 RE 匹配的所有子串,并把它们作为一个迭代器返回。
import re iter = re.finditer(re.compile(r'\d+'), 'jhdsafh12hdfsf34?56') for i in iter: print(i) # 迭代器 <re.Match object; span=(7, 9), match='12'> print(i.group()) # 值 12 print(i.span()) # 下标 (7,9)
-
split():此处为正则表达式中的分割
import re time = '2019-2-30 16:20:00' regex = re.compile(r'[- :]') res = re.split(regex,time) print(res) # ['2019', '2', '30', '16', '20', '00']
-
sub():替换
import re time = '2019-2-30 16:20:00' regex = re.compile(r'[- :]') res = re.sub(regex, ',', time) print(res) # 2019,2,30,16,20,00
-
-
贪婪匹配和非贪婪匹配
# 贪婪匹配 import re s='lookandlook' regex = re.compile(r'l\w*k') res = re.findall(regex, s) print('贪婪模式:',res) # 贪婪模式: ['lookandlook'] # 非贪婪匹配:*? +? ?? {m,n}? import re s='lookandlook' regex = re.compile(r'l\w*?k') res = re.findall(regex, s) print('非贪婪模式:',res) # 非贪婪模式: ['look', 'look'] s21 = '<H1>title</H1>' regex21 = re.compile(r'<.*>') res21 = re.match(regex21, s21) print(res21) # <re.Match object; span=(0, 14), match='<H1>title</H1>'> regex22 = re.compile(r'<.*?>') res22 = re.match(regex22, s21) print(res22) # <re.Match object; span=(0, 4), match='<H1>'>
-
re.match与re.search与re.findall的区别
re.match只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,函数返回None
re.search匹配整个字符串,直到找到一个匹配。
re.findall查找所有匹配的
a = re.search('[\d]', "abc33").group() print(a) # 3 p = re.match('[\d]', "abc33") print(p) # None b = re.findall('[\d]', "abc33") print(b) # ['3', '3']
-
简单爬虫
import re sss = ''' <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <li>001</li> <li>002</li> <li>003</li> <li>004</li> </body> </html> ''' regex_sss = re.compile(r'<li>(.+?)</li>') res_sss = re.findall(regex_sss, sss) print(res_sss)