665|6

6859

帖子

9

TA的资源

版主

楼主
 

《Python编程快速上手》7、正则表达式 [复制链接]

        正则表达式是一种匹配的方式,我们在进行多位字符查找是可能会通过不断的遍历比较进行对比,如果样本比较大可能需要非常多的次数进行判断,正则表达式的存在可以大大简化这个过程。
        正则表达式,简称为 regex,是文本模式的描述方法。例如,\d 是一个正则表达式,表示一位数字字符,即任何一位 0 到 9 的数字。Python 使用正则表达式 \d\d\d-\d\d\d-\d\d\d\d,来匹配前面 isPhoneNumber() 函数匹配的同样文本:3 个数字、一个短横线、3 个数字、一个短横线、4 个数字。所有其他字符串都不能匹配 \d\d\d-\d\d\d-\d\d\d\d 正则表达式。当然了正则表达式可以复杂得多。例如,在一个模式后加上花括号包围的 3({3}),就是说,“匹配这个模式 3 次”。所以较短的正则表达式 \d{3}-\d{3}-\d{4},也匹配正确的电话号码格式。
        Python 中所有正则表达式的函数都在 re 模块中,对于3.x版本的存储在 regex模块中:
                向 regex.compile() 传入一个字符串值,表示正则表达式,它将返回一个 Regex 模式对象(或者就简称为 Regex 对象);
                search 方法只匹配第一次,返回一个 Match 对象;
                findall() 方法匹配所有,返回一个字符串列表;
        本次加载import regex提示Unused import statement 'import regex',而且import regex为灰色,解决办法是通过Pycharm file 菜单下有Invalidate caches/Restart菜单栏,点击清除缓存重新启动Pycharm即可。
        本书用一个查找电话号码的例子让我们对其进行进一步体验比较:
  • import regex
  • def is_phone_number(text):
  • if len(text) != 12:
  • return False
  • for i in range(0, 3):
  • if not text[i].isdecimal():
  • return False
  • if text[3] != '-':
  • return False
  • for i in range(4, 7):
  • if not text[i].isdecimal():
  • return False
  • if text[7] != '-':
  • return False
  • for i in range(8, 12):
  • if not text[i].isdecimal():
  • return False
  • return True
  • message = 'Call me at 415-555-1011 tomorrow. 415-566-9999 is my office.'
  • a = 0
  • for a in range(len(message)):
  • chunk = message[a:a+12]
  • if is_phone_number(chunk):
  • print('Phone number found: ' + chunk)
  • print(a)
  • print('-------------')
  • phoneNumRegex = regex.compile(r'\d\d\d-\d\d\d-\d\d\d\d')
  • ob = phoneNumRegex.search(message)
  • print('First Phone number found: ' + ob.group())
  • print('-------------')
  • a = 0
  • obs = phoneNumRegex.findall(message)
  • for a in range(len(obs)):
  • chunk = obs[a]
  • print('Phone number found: ' + chunk)
  • print(a+1)
  • print('-------------')

结果如下:

有一些小技巧:
        使用括号可以分组,注意不要超过括号的数量,group(1) 对应第一个括号,group(0) 匹配全部;
        (使用括号分组后)使用groups()返回的是一个元组第一次匹配的,元组可以使用多重复制的技巧;findall()返回的列表元素也是元组;
        字符 | 称为“管道”,希望匹配许多表达式中的一个,返回第一个匹配成功的,例如A|B,首先和A匹配符合就不与B匹配了
  • import regex
  • message = 'Call me at 415-555-1011 tomorrow. 415-566-9999 is my office.'
  • phoneNumRegex = regex.compile(r'(\d\d\d)-\d\d\d-\d\d\d\d')
  • ob = phoneNumRegex.search(message)
  • print('First Phone number found: ' + ob.group())
  • print('-------------')
  • phoneNumRegex = regex.compile(r'(\d\d\d)-(\d\d\d)-(\d\d\d\d)')
  • ob = phoneNumRegex.search(message)
  • print('First Phone number found: ' + ob.group(2))
  • print(ob.groups())
  • obs = phoneNumRegex.findall(message)
  • print(obs)
  • print('-------------')
  • phoneNumRegex = regex.compile(r'\d\d\d\d|\d\d\d')
  • ob = phoneNumRegex.search(message)
  • print('First Phone number found: ' + ob.group())
  • obs = phoneNumRegex.findall(message)
  • print(obs)

结果如下:

        后面使用控制台进行验证,发现比程序要好用

        字符?表明它前面的分组在这个模式中是可选的:
  • batRegex = regex.compile(r'Bat(wo)?man')
  • mo1 = batRegex.search('The Adventures of Batman')
  • mo1.group()
  • 'Batman'
  • mo1.groups()
  • (None,)
  • mo1 = batRegex.findall('The Adventures of Batman')
  • findall
  • Traceback (most recent call last):
  • File "<input>", line 1, in <module>
  • NameError: name 'findall' is not defined
  • mo1
  • ['']
  • mo2 = batRegex.search('The Adventures of Batwoman')
  • mo2.group()
  • 'Batwoman'
  • mo3 = batRegex.search('The Adventures of Batman Batwoman')
  • mo3.group()
  • 'Batwoman'

        由上可见groups()和findall()方法不能用,返回的是空,加问号后如果有提前遍历返回;

        *(称为星号)意味着“匹配零次或多次”,即星号之前的分组,可以在文本中出现任意次。它可以完全不存在,或一次又一次地重复。+ 则意味着“匹配一次或多次”。星号不要求分组出现在匹配的字符串中,但加号不同,加号前面的分组必须“至少出现一次”。这不是可选的。
        如果想要一个分组重复特定次数,就在正则表达式中该分组的后面,跟上花括号包围的数字。例如,正则表达式 (Ha){3} 将匹配字符串 'HaHaHa',但不会匹配 'HaHa',因为后者只重复了 (Ha) 分组两次。可以不写花括号中的第一个或第二个数字,不限定最小值或最大值。例如,(Ha){3,} 将匹配 3 次或更多次实例,(Ha){,5} 将匹配 0 到 5 次实例。Python 的正则表达式默认是“贪心”的,这表示在有二义的情况下,它们会尽可能匹配最长的字符串。花括号的“非贪心”版本匹配尽可能最短的字符串,即在结束的花括号后跟着一个问号。
缩写字符分类如下:

        方括号定义自己的字符分类,例如[aeiouAEIOU] 将匹配所有元音字符;

        插入符号 ^ ,表明匹配必须发生在被查找文本开始处。类似地,可以再正则表达式的末尾加上美元符号 $ ,表示该字符串必须以这个正则表达式的模式结束;
        . 字符称为“通配符”。它匹配除了换行之外的所有字符;
        可以用 .* 表示“任意文本”。回忆一下,句点字符表示“除换行外所有单个字符”,星号字符表示“前面字符出现零次或多次”。
 
        正则表达式不仅能找到文本模式,而且能够用新的文本替换掉这些模式。Regex 对象的 sub() 方法需要传入两个参数。第一个参数是一个字符串,用于取代发现的匹配。第二个参数是一个字符串,即正则表达式;
        向 re.compile() 传入变量 re.VERBOSE,作为第二个参数,可以忽略正则表达式字符串中的空白符和注释;
        向 re.compile() 传入变量re.IGNORECASE作为第二个参数,来忽略大小写;第二参数可以通过“按位或”操作符同时起作用;

最新回复

很详细  详情 回复 发表于 2024-5-17 13:42
点赞 关注
个人签名

在爱好的道路上不断前进,在生活的迷雾中播撒光引

 
 

回复
举报

7188

帖子

11

TA的资源

版主

沙发
 

正则表达式不仅能找到文本模式,而且能够用新的文本替换掉这些模式。Regex 对象的 sub() 方法需要传入两个参数。第一个参数是一个字符串,用于取代发现的匹配。第二个参数是一个字符串,即正则表达式;

        向 re.compile() 传入变量 re.VERBOSE,作为第二个参数,可以忽略正则表达式字符串中的空白符和注释;

        向 re.compile() 传入变量re.IGNORECASE作为第二个参数,来忽略大小写;第二参数可以通过“按位或”操作符同时起作用;

我现在对正则还是没有学习好,恭喜版主大佬喜得这么好的读书机会。

点评

从这节开始,难度直接拉上去了,各种使用技巧,根本记不过来啊   详情 回复 发表于 2024-5-16 09:30
 
 
 

回复

6859

帖子

9

TA的资源

版主

板凳
 
lugl4313820 发表于 2024-5-16 07:38 正则表达式不仅能找到文本模式,而且能够用新的文本替换掉这些模式。Regex 对象的 sub() 方法需要传入两个 ...

从这节开始,难度直接拉上去了,各种使用技巧,根本记不过来啊 

个人签名

在爱好的道路上不断前进,在生活的迷雾中播撒光引

 
 
 

回复

161

帖子

0

TA的资源

一粒金砂(高级)

4
 

通过示例去测试可以大大加深印象,而且直观

 
 
 

回复

1489

帖子

1

TA的资源

五彩晶圆(初级)

5
 

是不是有那种RegEx的手册,专门讲字符模式的?

当然必须实践才可以熟能生巧。。。。。

点评

我也不是很懂,作为初学者安装这些三方固件都是各种问题呢  详情 回复 发表于 2024-5-16 14:17
 
 
 

回复

6859

帖子

9

TA的资源

版主

6
 
hellokitty_bean 发表于 2024-5-16 13:44 是不是有那种RegEx的手册,专门讲字符模式的? 当然必须实践才可以熟能生巧。。。。。

我也不是很懂,作为初学者安装这些三方固件都是各种问题呢

个人签名

在爱好的道路上不断前进,在生活的迷雾中播撒光引

 
 
 

回复

258

帖子

3

TA的资源

一粒金砂(高级)

7
 

很详细


 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条
有奖直播报名| TI 面向楼宇和工厂自动化行业的毫米波雷达解决方案
【内容简介】TI 60GHz IWRL6432和 IWRL1432毫米波雷达传感器如何帮助解决楼宇和工厂自动化应用中的感应难题
【直播时间】5月28日(周三)上午10:00
【直播礼品】小米双肩包、contigo水杯、胶囊伞、安克充电器

查看 »

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网 12

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表