数据解析之正则

正则表达式

1、匹配单个字符与数字

匹配说明
. 匹配除换行符以外的任意字符,当flags被设置为re.S时,可以匹配包含换行符以内的所有字符
[] 里面是字符集合,匹配[]里任意一个字符
[0123456789] 匹配任意一个数字字符
[0-9] 匹配任意一个数字字符
[a-z] 匹配任意一个小写英文字母字符
[A-Z] 匹配任意一个大写英文字母字符
[A-Za-z] 匹配任意一个英文字母字符
[A-Za-z0-9] 匹配任意一个数字或英文字母字符
[^lucky] []里的^称为脱字符,表示非,匹配不在[]内的任意一个字符
^[lucky] 以[]中内的某一个字符作为开头
\d 匹配任意一个数字字符,相当于[0-9]
\D 匹配任意一个非数字字符,相当于[^0-9]
\w 匹配字母、下划线、数字中的任意一个字符,相当于[0-9A-Za-z_]
\W 匹配非字母、下划线、数字中的任意一个字符,相当于[^0-9A-Za-z_]
\s 匹配空白符(空格、换页、换行、回车、制表),相当于[ \f\n\r\t]
\S 匹配非空白符(空格、换页、换行、回车、制表),相当于[^ \f\n\r\t]

 

2、匹配锚字符

锚字符:用来判定是否按照规定开始或者结尾

匹配说明
^ 行首匹配,和[]里的^不是一个意思
$ 行尾匹配
\A 匹配字符串的开始,和^的区别是\A只匹配整个字符串的开头,即使在re.M模式下也不会匹配其他行的行首
\Z 匹配字符串的结尾,和$的区别是\Z只匹配整个字符串的结尾,即使在re.M模式下也不会匹配其他行的行尾

 

3、限定符

限定符用来指定正则表达式的一个给定组件必须要出现多少次才能满足匹配。有 * 或 + 或 ? 或 {n} 或 {n,} 或 {n,m} 共6种。

匹配说明
(xyz) 匹配括号内的xyz,作为一个整体去匹配 一个单元 子存储
x? 匹配0个或者1个x,非贪婪匹配
x* 匹配0个或任意多个x
x+ 匹配至少一个x
x{n} 确定匹配n个x,n是非负数
x{n,} 至少匹配n个x
x{n,m} 匹配至少n个最多m个x
x|y |表示或的意思,匹配x或y

re模块中常用函数

通用flags(修正符)

说明
re.I 是匹配对大小写不敏感
re.M 多行匹配,影响到^和$
re.S 使.匹配包括换行符在内的所有字符

 

 

通用函数

  • 获取匹配结果

    • 使用group()方法 获取到匹配的值

    • groups() 返回一个包含所有小组字符串的元组(也就是自存储的值),从 1 到 所含的小组号。

1、match()函数

原型:

def match(pattern, string, flags=0)

功能:

匹配成功返回 匹配的对象

匹配失败 返回 None

获取匹配结果:

  • 使用group()方法 获取到匹配的值

  • groups() 返回一个包含所有小组字符串的元组,从 1 到 所含的小组号。

注意:从第一位开始匹配  只匹配一次

参数:

参数说明
pattern 匹配的正则表达式(一种字符串的模式)
string 要匹配的字符串
flags

标识位,用于控制正则表达式的匹配方式

代码:

import re

res = re.match('\d{2}','123')
print(res.group())
print(res.span())

#给当前匹配到的结果起别名
s = '3G4HFD567'
re.match("(?P<value>\d+)",s)
print(x.group(0))
print(x.group('value'))

2、searce()函数

原型:

def search(pattern, string, flags=0)

功能:

扫描整个字符串string,并返回第一个pattern模式成功的匹配

匹配失败 返回 None

参数:

参数说明
pattern 匹配的正则表达式(一种字符串的模式)
string 要匹配的字符串
flags 标识位,用于控制正则表达式的匹配方式

注意:

只要字符串包含就可以

只匹配一次

注意

与search的区别

相同点:

都只匹配一次

不同点:

search是在要匹配的字符串中 包含正则表达式的内容就可以

match 必须第一位就开始匹配 否则匹配失败

3、findall()函数(返回列表)

原型:

def findall(pattern, string, flags=0)

功能:

扫描整个字符串string,并返回所有匹配的pattern模式结果的字符串列表

参数:

参数说明
pattern 匹配的正则表达式(一种字符串的模式)
string 要匹配的字符串
flags 标识位,用于控制正则表达式的匹配方式

示例

myStr = """
<a href="http://www.baidu.com">百度</a>
<A href="http://www.taobao.com">淘宝</A>
<a href="http://www.id97.com">电
影网站</a>
<i>我是倾斜1</i>
<i>我是倾斜2</i>
<em>我是倾斜2</em>
"""
# html里是不区分大小写
# (1)给正则里面匹配的 加上圆括号 会将括号里面的内容进行 单独的返回
res = re.findall("(<a href=\"http://www\.(.*?)\.com\">(.*?)</a>)",myStr) #[('<a href="http://www.baidu.com">百度</a>', 'baidu', '百度')]

# 括号的区别
res = re.findall("<a href=\"http://www\..*?\.com\">.*?</a>",myStr) #['<a href="http://www.baidu.com">百度</a>']

#(2) 不区分大小写的匹配
res = re.findall("<a href=\"http://www\..*?\.com\">.*?</a>",myStr,re.I) #['<a href="http://www.baidu.com">百度</a>', '<A href="http://www.taobao.com">淘宝</A>']
res = re.findall("<[aA] href=\"http://www\..*?\.com\">.*?</[aA]>",myStr) #['<a href="http://www.baidu.com">百度</a>']

使.支持换行匹配

res = re.findall("<a href="http://www..?.com">.?</a>",myStr,re.S) #

支持换行 支持不区分大小写匹配

res = re.findall("<a href="http://www..?.com">.?</a>",myStr,re.S|re.I) #

print(res)

- 贪婪与非贪婪模式

```html
<H1>Chapter 1 - 介绍正则表达式</H1>

贪婪:下面的表达式匹配从开始小于符号 (<) 到关闭 H1 标记的大于符号 (>) 之间的所有内容。

/<.*>/

非贪婪:如果您只需要匹配开始和结束 H1 标签,下面的非贪婪表达式只匹配 <H1>

/<.*?>/

如果只想匹配开始的 H1 标签,表达式则是:

/<\w+?>

4、finditer()函数

原型:

def finditer(pattern, string, flags=0)

功能:

与findall()类似,返回一个迭代器(需要for循环)

参数:

参数说明
pattern 匹配的正则表达式(一种字符串的模式)
string 要匹配的字符串
flags 标识位,用于控制正则表达式的匹配方式

代码:

import re

res = re.finditer('\w', '12hsakda1')
print(res)
print(next(res))

for i in res:
print(i)

5、split()函数

作用:切割字符串

原型:

def split(patter, string, maxsplit=0, flags=0)

参数:

pattern 正则表达式

string 要拆分的字符串

maxsplit 最大拆分次数 默认拆分全部

flags 修正符

示例:

import re
myStr = "asdas\rd&a\ts12d\n*a3sd@a_1sd"
#通过特殊字符 对其进行拆分 成列表
res = re.split("[^a-z]",myStr)
res = re.split("\W",myStr)

6、修正符

作用:

对正则进行修正

使用:

search/match/findall/sub/subn/finditer 等函数 flags参数的使用

修正符:

re.I 不区分大小写匹配

re.M 多行匹配 影响到^ 和 $ 的功能

re.S 使.可以匹配换行符 匹配任意字符

使用:

re.I

print(re.findall('[a-z]','AaBb'))
print(re.findall('[a-z]','AaBb', flags=re.I))

re.M(实际)

myStr = """asadasdd1\nbsadasdd2\ncsadasdd3"""
print(re.findall('^[a-z]',myStr, ))
print(re.findall('\A[a-z]',myStr))
print(re.findall('\d$',myStr))
print(re.findall('\d\Z',myStr))
# re.M
print(re.findall('^[a-z]',myStr, flags=re.M))
print(re.findall('\A[a-z]',myStr, flags=re.M))
print(re.findall('\d$',myStr, flags=re.M))
print(re.findall('\d\Z',myStr, flags=re.M))

re.S

print(re.findall('<b>.*?</b>','<b>b标签</b>'))
print(re.findall('<b>.*?</b>','<b>b标\n签</b>', flags=re.S))

正则高级

1、分组&起名称

概念:

处理简单的判断是否匹配之外,正则表达式还有提取子串的功能,用()表示的就是要提取的分组

代码:

#给当前匹配到的结果起别名
s = '3G4HFD567'
re.match("(?P<value>\d+)",s)
print(x.group(0))
print(x.group('value'))

说明:

  • 正则表达式中定义了组,就可以在Match对象上用group()方法提取出子串来

  • group(0)永远是原始字符串,group(1)、group(2)……表示第1、2、……个子串

2、编译

概念:

当在python中使用正则表达式时,re模块会做两件事,一件是编译正则表达式,如果表达式的字符串本身不合法,会报错。另一件是用编译好的正则表达式提取匹配字符串

编译优点:

如果一个正则表达式要使用几千遍,每一次都会编译,出于效率的考虑进行正则表达式的编译,就不需要每次都编译了,节省了编译的时间,从而提升效率

compile()函数:

原型:

def compile(pattern, flags=0)

作用:

将pattern模式编译成正则对象

参数:

参数说明
pattern 匹配的正则表达式(一种字符串的模式)
flags 标识位,用于控制正则表达式的匹配方式

flags

 

说明
re.I 是匹配对大小写不敏感
re.M 多行匹配,影响到^和$
re.S 使.匹配包括换行符在内的所有字符

返回值

编译好的正则对象

示例

import re

re_phone = re.compile(r"(0\d{2,3}-\d{7,8})")
print(re_phone, type(re_phone))

编译后其他方法的使用

原型

def match(self, string, pos=0, endpos=-1)
def search(self, string, pos=0, endpos=-1)
def findall(self, string, pos=0, endpos=-1)
def finditer(self, string, pos=0, endpos=-1)

参数

参数说明
string 待匹配的字符串
pos 从string字符串pos下标开始
endpos 结束下标

示例

s1 = "lucky's phone is 010-88888888"
s2 = "kaige's phone is 010-99999999"
ret1 = re_phone.search(s1)
print(ret1, ret1.group(1))
ret2 = re_phone.search(s2)
print(ret2, ret2.group(1))

3、贪婪与非贪婪

贪婪模式

贪婪概念:匹配尽可能多的字符

  • .+ 匹配换行符以外的字符至少一次

  • .* 匹配换行符以外的字符任意次

实例

res = re.search('<b>.+</b>', '<b></b><b>b标签</b>')
res = re.search('<b>.*</b>', '<b>b标签</b><b>b标签</b><b>b标签</b><b>b标签</b>')

非贪婪模式

非贪婪概念:尽可能少的匹配称为非贪婪匹配,*?、+?即可

.+? 匹配换行符以外的字符至少一次 拒绝贪婪

  • .*? 匹配换行符以外的字符任意次 拒绝贪婪

实例

res = re.search('<b>.+?</b>', '<b>b标签</b><b>b标签</b>')
res = re.search('<b>.*?</b>', '<b>b标签</b><b>b标签</b><b>b标签</b><b>b标签</b>')

 

                                                                                                                                                                                                                                                                                                         

 

posted @   星尘yuan  阅读(180)  评论(0编辑  收藏  举报
努力加载评论中...
点击右上角即可分享
微信分享提示