欢迎来到Louis的博客

人生三从境界:昨夜西风凋碧树,独上高楼,望尽天涯路。 衣带渐宽终不悔,为伊消得人憔悴。 众里寻他千百度,蓦然回首,那人却在灯火阑珊处。
扩大
缩小

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)

# 正则表达式如果写的足够好的话 能够最大限度的简化我们的操作

 

posted on 2018-08-17 17:43  Louiszj  阅读(177)  评论(0编辑  收藏  举报

导航