re 模块
re -正则表达式操作
在python中re模块提供使用正则表达式来处理字符串的功能,所以在学习该模块之前,还需要了解正正则表达式的语法规则,正则表达式教程
正则表达式使用反斜杠字符('\')来表示特殊形式或允许使用特殊字符而不调用它们的特殊含义。这与Python对字符串文字中相同用途的相同字符的使用相冲突; 例如,要匹配文字反斜杠,可能必须将'\\\\'写为模式字符串,因为正则表达式必须为\\,并且每个反斜杠必须在常规Python字符串文字中表示为\\。
解决方案是使用Python的原始字符串表示法来表示正则表达式模式; 在前缀为'r'的字符串文字中,不会以任何特殊方式处理反斜杠。因此r“\ n”是包含'\'和'n'的双字符字符串 ,而“\ n”是包含换行符的单字符字符串。通常,模式将使用此原始字符串表示法在Python代码中表示。
re模块官方文档
re 模块方法
findall
findall(pattern, string, flags=0) ---> list
根据正则表达式,匹配字符串,返回所有匹配结果组成的列表
>>> import re >>> s = "abcd12kashdiwjfuoiw3467aksjdwldjw321" >>> ret = re.findall('\d+', s) >>> ret ['12', '3467', '321'] >>>
search
re.search(pattern, staring, flags) --> re.Match.object
只匹配从左到右的第一个,返回的是一个re.match对象,通过这个对象的group方法获取匹配到的值,如果没有匹配到结果,返回的是None
ret = re.search('\d+', s) print(ret) print(ret.group()) #result <re.Match object; span=(0, 3), match='123'> 123
ret = re.search('[^\w]]', s) #没有匹配到结果
print(ret)
#result
None
match
re.match(pattern, string, flags=0) --> re.Match.object
从头开始匹配,相当于search中的正则表达式前面加上一个^,返回一个re.Match.object对象,通过这个对象的group方法获取匹配到的值,如果没有匹配到结果,返回的是None
ret = re.match('\d+', s) print(ret) print(ret.group()) #result <re.Match object; span=(0, 3), match='123'> 123
split
re.split(pattern, string,maxsplit=0, flags=0) --> list
根据正则表达式切割字符串,maxsplit为最大切割次数默认为0,切割所有,返回一个结果组成的列表
ret = re.split('[a-zA-Z]+', s) print(ret) #result ['123', '98123', '01', '2', '091', '091']
sub
sub(pattern, repl, string, count=0, flags=0) ->string
通过正则表达式替换匹配到的内容,repl为替换后的内容和,count替换的次数,返回新的字符串
ret = re.sub('[a-zA-Z]+', "七夕哈哈哈",s) print(ret)
#result
123七夕哈哈哈98123七夕哈哈哈01七夕哈哈哈2七夕哈哈哈091七夕哈哈哈091
ret = re.sub('[a-zA-Z]+', "七夕哈哈哈",s,1) # 替换一次
print(ret)
#result
123七夕哈哈哈98123ndlasnf01po2ijponlasjd091jndlasj091
subn
subn(pattern, repl, string, count=0, flags=0)
功能跟sub一样,但是返回一个二元组,第一个元素为新字符串,第二个为替换的次数。
ret = re.subn('[a-zA-Z]+', "七夕哈哈哈", s) print(ret) #result ('123七夕哈哈哈98123七夕哈哈哈01七夕哈哈哈2七夕哈哈哈091七夕哈哈哈091', 5)
compile
re.compile(pattern, flags=0)
将正则表达式进行编译,编译成字节码,在多次使用的过程中,不会在次编译,节省使用正则表达式的时间,当正则较长时,可以使用该方法进行编译,优化程序执行时间。
r = re.compile('\d+') print(r) ret = r.findall(s) print(ret) ret = r.search(s) print(ret.group()) ret = r.sub("七夕哈哈哈哈哈",s) print(ret) #reslut re.compile('\\d+') ['123', '98123', '01', '2', '091', '091'] 123 七夕哈哈哈哈哈ih七夕哈哈哈哈哈ndlasnf七夕哈哈哈哈哈po七夕哈哈哈哈哈ijponlasjd七夕哈哈哈哈哈jndlasj七夕哈哈哈哈哈
finditer
re.finditer(pattern, string, flags=0) -> 返回一个可迭代对象
finditer和findall其实功能是一定的,不同的是在返回值上,findall是直接返回所有的匹配结果,finditer是返回一个包含匹配的迭代器,由于迭代器的惰性取值的情况,finditer在数据量很大的时候可以很节省内存
<callable_iterator object at 0x101e839b0> 123 98123 01 2 091 091
分组
import re # s = '<a>wahaha</a>' # 标签语言 html 网页 # ret = re.search('<(\w+)>(\w+)</(\w+)>',s) # print(ret.group()) # 所有的结果 # print(ret.group(1)) # 数字参数代表的是取对应分组中的内容 # print(ret.group(2)) # print(ret.group(3))
在使用search时,正则表达式分组可以用来获取匹配结果中的多个值
s1 = ''' <a>wahaha</a> <b>banana</b> <h1>qqxing</h1> ''' ret = re.search('<(\w+)>(\w+)</(\w+)>',s1) print(ret.group()) print(ret.group(1)) print(ret.group(2)) print(ret.group(3)) #result <a>wahaha</a> a wahaha a
在使用findall时使用分组,将只会返回分组中的内容,如果有多个分组则会将多个分组的结果组成一个元组,然后放到list中返回。
ret = re.findall('>(\w+)<', s1) print(ret) #result ['wahaha', 'banana', 'qqxing'] ret = re.findall('(>)(\w+)(<)', s1) print(ret) #result [('>', 'wahaha', '<'), ('>', 'banana', '<'), ('>', 'qqxing', '<')]
然而在有些时候我们不希望使用分组,但python中又是默认分组优先的,可以使用下面的方法取消分组优先
# 取消分组优先(?:正则表达式)
s = '123.123' ret = re.findall(r'\d+(?:\.\d+)?', s) print(ret) #result ['123.123']
# 关于分组 # 对于正则表达式来说 有些时候我们需要进行分组,来整体约束某一组字符出现的次数 # (\.[\w]+)? # 对于python语言来说 分组可以帮助你更好更精准的找到你真正需要的内容 # <(\w+)>(\w+)</(\w+)>
分组命名:(?P<这个组的名字>正则表达式)
s1 = ''' <a>wahaha</a> <b>banana</c> <h1>qqxing</h1> ''' ret = re.findall(r'<(?P<tag>\w+)>(\w+)</(?P=tag)>', s1) # 这种可以用于判断是否是有效标签
ret = print(ret) #result [('a', 'wahaha'), ('h1', 'qqxing')]
ret = re.findall(r'<(\w+)>(\w+)</(\1)>', s1)
print(ret)
result
[('a', 'wahaha', 'a'), ('h1', 'qqxing', 'h1')]
一些正则使用的技巧
# ret=re.findall(r"\d+","1-2*(60+(-40.35/5)-(-4*3))") # 从"1-2*(60+(-40.35/5)-(-4*3))"中取整数 # ['1', '2', '60', '40', '35', '5', '4', '3'] # print(ret) # 你要匹配的内容太没有特点了 容易和你不想匹配的内容混在一起 # 精准的取到整数 过滤掉小数 ret=re.findall(r"\d+\.\d+|\d+","1-2*(60+(-40.35/5)-(-4*3))") print(ret) ret=re.findall(r"\d+\.\d+|(\d+)","1-2*(60+(-40.35/5)-(-4*3))") ret.remove('') print(ret) # 正则表达式如果写的足够好的话 能够最大限度的简化我们的操作