Python中正则表达式的正确使用是怎样的

Admin 2022-06-23 群英技术资讯 288 次浏览

这篇文章给大家分享的是“Python中正则表达式的正确使用是怎样的”,对大家学习和理解有一定的参考价值和帮助,有这方面学习需要的朋友,接下来就跟随小编一起学习一下吧。

1. 什么是正则表达式

正则表达式(Regular Expressions),也称为 “regex” 或 “regexp” 是使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串,这样程序就可以将该模式与任意文本字符串相匹配。

使用正则表达式,可以为要匹配的可能字符串集指定规则;此集可能包含英语句子,电子邮件地址,TeX命令或你喜欢的任何内容

正则表达式引擎

采用不同算法,检查处理正则表达式的软件模块 PCRE (perl compatible regular expressions)

正则表达式的元字符分类: 字符匹配,匹配次数,位置锚定,分组

Python的正则表达式是PCRE标准的。

2. 正则表达式基础

# 字符匹配

. 匹配任意单个字符(换行符除外)

[]匹配指定范围内的任意单个字符: [0-9] [a-z]

^[xxx]以[]内的任意字符开头

[^xxx]: 除了[]内的字符,相当于取反

# 匹配次数

用于指定前面的字符要出现几次

* 匹配前面的字符的任意次,包括0次, 贪婪匹配:尽可能长的匹配
.* 任意长度的任意字符
? 匹配其前面的字符0或1次
+ 匹配前面的字符至少1次
{n} 匹配前面的字符n次
{m,n} 匹配前面的字符至少m次,最多n次如{1,3} 匹配1到3次
{n,} 匹配前面的字符至少n次

# 位置锚定
# 用于定位出现的位置

^ 行首

$ 行尾

^$ 空行

# 分组
() 分组,用()将多个字符捆绑在一起,当作一个整体处理
后向引用: \1,\2

# | 或者
a|b a 或 b
(A|a)bc Abc或abc

# \ 转义
\ 反斜杠后面可以跟各种字符,以指示各种特殊序列。它也用于转义所有元字符.因此您仍然可以在模式中匹配它们,如果你需要匹配 [ 或 \,你可以在它们前面加一个反斜杠来移除它们的特殊含义:\[ 或 \\。
在python中取消转义推荐使用r,如果要匹配'\n',因为'\n'有特殊含义:回车。要匹配'\n'可以以写'\\n',在Python中可以使用r'\n'。

\d 匹配任何十进制数,等价于类 [0-9]
\w 匹配任何字母与数字字符包括下划线;这相当于类 [a-zA-Z0-9_]。
\s 匹配任何空白字符;这等价于类 [ \t\n\r\f\v]。

\D 匹配任何非数字字符;这等价于类 [^0-9]。
\W 匹配任何非字母与数字字符;这相当于类 [^a-zA-Z0-9_]。
\S 匹配任何非空白字符;这相当于类 [^ \t\n\r\f\v]。

3. Python中使用正则表达式

在python中使用正则表达式常用的模块为:re。

3.1 re常用的方法

# re.findall('正则表达式','待匹配的文本')  根据正则匹配出所有符合条件的数据,返回列表
>>> re.findall('[0-9]', "Hello world 123")
['1', '2', '3']
# 如果匹配不到findall返回一个空列表

# re.finditer('正则表达式','待匹配的文本') 根据正则匹配出所有符合条件的数据,返回一个对象
>>> re.finditer('[0-9]', "Hello world 123")     
<callable_iterator object at 0x7f3409296d68>
# 取值:
>>> res = re.finditer('[0-9]', "Hello world 123")
>>> for i in res:
...     print(i.group())
... 
1
2
3

# 如果匹配不到finditer返回空。

# findall 和finditer功能一样,但是finditer更节省内存。

# re.search('正则表达式','待匹配的文本')   根据正则匹配到一个符合条件的就结束
>>> res = re.search('l', "Hello world 123")     
>>> res
<_sre.SRE_Match object; span=(2, 3), match='l'>
>>> res.group()
'l'
# 匹配到一个就返回,group()返回具体的元素,如果匹配不到search返回None,使用group取值就会报错:
AttributeError: 'NoneType' object has no attribute 'goup'
    
# re.match('正则表达式','待匹配的文本') 根据正则从头开始匹配(文本内容必须在开头匹配上)
>>> res = re.match('e', "Hello world 123")   # e 不在开头,所以匹配不上,返回None
>>> print(res)
None

>>> res = re.match('H', "Hello world 123")  # H 为开头能匹配上
>>> print(res)
<_sre.SRE_Match object; span=(0, 1), match='H'>
>>> print(res.group())
H

#如果没有匹配到,match会返回None 使用group取值的时候也会直接报错
AttributeError: 'NoneType' object has no attribute 'group'


# search和match匹配不到都会报错,可以处理一下:
if res:
    print(res.group())
else:
    print('没有匹配到')
    
# re.split 分割
>>> re.split('[0-9]', "Hello 123 world")    # 按匹配到的分割,返回一个列表   
['Hello ', '', '', ' world'] 

# re.sub('要匹配的', '要替换的', '文本')  替换
>>> re.sub('[0-9]','A', "Hello 123 world")  # 默认替换全部
'Hello AAA world'
>>> re.sub('[0-9]','A', "Hello 123 world",1) # 替换一次
'Hello A23 world'
>>> re.sub('[0-9]','A', "Hello 123 world",2) # 替换两次
'Hello AA3 world'
# re.subn() 和re.sub 功能一样,但是返回元组 并提示替换了几处
>>> re.subn('[0-9]','A', "Hello 123 world")    
('Hello AAA world', 3)
>>> re.subn('[0-9]','A', "Hello 123 world", 1)
('Hello A23 world', 1)

# 如果一个正则表达式在程序中经常用到,这样每次都写太麻烦,可以使用compile将正则表达式的样式编译为一个正则表达式对象 (正则对象)
# 例如 正则表达式'^\d{3,6}'经常使用
>>> obj = re.compile('^\d{3,6}')
>>> obj.findall("123 Hello")
['123']
>>> res = obj.search("123 Hello")
>>> res.group()
'123'
# obj还可以使用 finditer,match,split,subn,sub

# 分组
>>> res = re.search('[1-9]\d{16}([0-9x])','37152119841105155x')   
>>> res.group()
'37152119841105155x'
>>> res.group(1)  # 只打印分组1里的内容,1为第一个分组,这里面只有([0-9x])所以打印x
'x'
>>> res = re.search('[1-9](\d{16})([0-9x])','37152119841105155x')
>>> res.group() 
'37152119841105155x'
>>> res.group(1)   # (\d{16}) 为第1个分组
'7152119841105155'
>>> res.group(2)	# ([0-9x]) 为第2个分组
'x'
# 这种取分组里的值也为索引取值

# findall优先打印出分组里的内容
>>> re.findall('[1-9]\d{16}([0-9x])','37152119841105155x')
['x']

# 取消分组: ?:
>>> res = re.findall('[1-9]\d{16}(?:[0-9x])','37152119841105155x')  
>>> res   # (?:[0-9x])
['37152119841105155x']

# 上面的分组为无名分组,分组也可以有名字。
# 有名分组  ?P<分组名称>
>>> res = re.search('[1-9](?P<first>\d{16})(?P<second>[0-9x])','37152119841105155x')
>>> res.group()
'37152119841105155x'
>>> res.group('first')
'7152119841105155'
>>> res.group('second')
'x'
# 分组后也可以使用索引到值:
>>> res.group(2)       
'x'

3.2 re模块练习

爬链家二手房前十页

import re
import requests 

for i in range(1,11):

    url = 'https://bj.lianjia.com/ershoufang/pg{}srs%E6%97%A7%E5%AE%AB/'.format(i)

    r = requests.get(url)

    title = re.findall('data-is_focus="" data-sl="">(.*?)</a>',r.text)
    price = re.findall('<span>([0-9]{3})</span>',r.text)

    address = re.findall('data-log_index="\d" data-el="region">(.*?)</a>', r.text)
    houseIcon = re.findall('<span class="houseIcon"></span>(.*?)</div>', r.text)



    res = zip(title,price,address,houseIcon)
    for i in res:
    # print("%s \t%s(万) \t%s\t%s" % (i[0], i[1], i[2], i[3])) 
        print("""
    小区名: %s,
    总价: %s万,
    地址: %s,
    房型: %s""" % (i[0], i[1], i[2], i[3]))
    
# 执行结果:
[root@hans_tencent_centos82 module]# python3 houses.py 

    小区名: 红星楼小区 南北通透一居室 满五唯一商品房,
    总价: 185万,
    地址: 红星楼 ,
    房型: 1室1厅 | 46.46平米 | 南 北 | 简装 | 顶层(共6层) | 1989年建 | 板楼

    小区名: 旧宫北里 2室2厅 南 北,
    总价: 469万,
    地址: 旧宫北里 ,
    房型: 2室2厅 | 96.55平米 | 南 北 | 精装 | 高楼层(共9层) | 2004年建 | 板楼

    小区名: 亦庄北岸 3室1厅 南 北,
    总价: 558万,
    地址: 亦庄北岸 ,
    房型: 3室1厅 | 109.58平米 | 南 北 | 精装 | 中楼层(共15层) | 2008年建 | 板塔结合

参考内容:

Python官方文档

内容扩展:

Python对正则表达式的支持

Python提供了re模块来支持正则表达式相关操作,下面是re模块中的核心函数。

函数 说明
compile(pattern, flags=0) 编译正则表达式返回正则表达式对象
match(pattern, string, flags=0) 用正则表达式匹配字符串 成功返回匹配对象 否则返回None
search(pattern, string, flags=0) 搜索字符串中第一次出现正则表达式的模式 成功返回匹配对象 否则返回None
split(pattern, string, maxsplit=0, flags=0) 用正则表达式指定的模式分隔符拆分字符串 返回列表
sub(pattern, repl, string, count=0, flags=0) 用指定的字符串替换原字符串中与正则表达式匹配的模式 可以用count指定替换的次数
fullmatch(pattern, string, flags=0) match函数的完全匹配(从字符串开头到结尾)版本
findall(pattern, string, flags=0) 查找字符串所有与正则表达式匹配的模式 返回字符串的列表
finditer(pattern, string, flags=0) 查找字符串所有与正则表达式匹配的模式 返回一个迭代器
purge() 清除隐式编译的正则表达式的缓存
re.I / re.IGNORECASE 忽略大小写匹配标记
re.M / re.MULTILINE 多行匹配标记

说明: 上面提到的re模块中的这些函数,实际开发中也可以用正则表达式对象的方法替代对这些函数的使用,如果一个正则表达式需要重复的使用,那么先通过compile函数编译正则表达式并创建出正则表达式对象无疑是更为明智的选择。


到此这篇关于“Python中正则表达式的正确使用是怎样的”的文章就介绍到这了,更多相关Python中正则表达式的正确使用是怎样的内容,欢迎关注群英网络技术资讯频道,小编将为大家输出更多高质量的实用文章! 群英智防CDN,智能加速解决方案

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。

猜你喜欢

成为群英会员,开启智能安全云计算之旅

立即注册
专业资深工程师驻守
7X24小时快速响应
一站式无忧技术支持
免费备案服务
免费拨打  400-678-4567
免费拨打  400-678-4567 免费拨打 400-678-4567 或 0668-2555555
在线客服
微信公众号
返回顶部
返回顶部 返回顶部
在线客服
在线客服