当前位置:网站首页>《Python Cookbook 3rd》笔记(2.4):字符串匹配和搜索
《Python Cookbook 3rd》笔记(2.4):字符串匹配和搜索
2020-11-10 10:46:00 【巨輪】
字符串匹配和搜索
问题
你想匹配或者搜索特定模式的文本
解法
如果你想匹配的是字面字符串,那么你通常只需要调用基本字符串方法就行,比如 str.find() , str.endswith() , str.startswith() 或者类似的方法:
>>> text = 'yeah, but no, but yeah, but no, but yeah'
>>> # Exact match
>>> text == 'yeah'
False
>>> # Match at start or end
>>> text.startswith('yeah')
True
>>> text.endswith('no')
False
>>> # Search for the location of the first occurrence
>>> text.find('no')
10
>>>
对于复杂的匹配需要使用正则表达式和 re 模块。为了解释正则表达式的基本原理,假设你想匹配数字格式的日期字符串比如 11/27/2012 ,你可以这样做:
>>> text1 = '11/27/2012'
>>> text2 = 'Nov 27, 2012'
>>>
>>> import re
>>> # Simple matching: \d+ means match one or more digits
>>> if re.match(r'\d+/\d+/\d+', text1):
... print('yes')
... else:
... print('no')
...
yes
>>> if re.match(r'\d+/\d+/\d+', text2):
... print('yes')
... else:
... print('no')
...
no
>>>
如果你想使用同一个模式去做多次匹配,你应该先将模式字符串预编译为模式对象。比如:
>>> datepat = re.compile(r'\d+/\d+/\d+')
>>> if datepat.match(text1):
... print('yes')
... else:
... print('no')
...
yes
>>> if datepat.match(text2):
... print('yes')
... else:
... print('no')
...
no
>>>
match() 总是从字符串开始去匹配,如果你想查找字符串任意部分的模式出现位置,使用 findall() 方法去代替。比如:
>>> text = 'Today is 11/27/2012. PyCon starts 3/13/2013.'
>>> datepat.findall(text)
['11/27/2012', '3/13/2013']
>>>
在定义正则式的时候,通常会利用括号去捕获分组。比如:
>>> datepat = re.compile(r'(\d+)/(\d+)/(\d+)')
>>>
捕获分组可以使得后面的处理更加简单,因为可以分别将每个组的内容提取出来。比如:
>>> m = datepat.match('11/27/2012')
>>> m
<_sre.SRE_Match object at 0x1005d2750>
>>> # Extract the contents of each group
>>> m.group(0)
'11/27/2012'
>>> m.group(1)
'11'
>>> m.group(2)
'27'
>>> m.group(3)
'2012'
>>> m.groups()
('11', '27', '2012')
>>> month, day, year = m.groups()
>>>
>>> # Find all matches (notice splitting into tuples)
>>> text
'Today is 11/27/2012. PyCon starts 3/13/2013.'
>>> datepat.findall(text)
[('11', '27', '2012'), ('3', '13', '2013')]
>>> for month, day, year in datepat.findall(text):
... print('{}-{}-{}'.format(year, month, day))
...
2012-11-27
2013-3-13
>>>
findall() 方法会搜索文本并以列表形式返回所有的匹配。如果你想以迭代方式返回匹配,可以使用 finditer() 方法来代替,比如:
>>> for m in datepat.finditer(text):
... print(m.groups())
...
('11', '27', '2012')
('3', '13', '2013')
>>>
讨论
本文阐述了使用 re模块进行匹配和搜索文本的最基本方法。核心步骤就是先使用 re.compile() 编译正则表达式字符串,然后使用 match() , findall() 或者 finditer() 等方法。
当写正则式字符串的时候,相对普遍的做法是使用原始字符串比如 r'(\d+)/(\d +)/(\d+)' 。这种字符串将不去解析反斜杠,这在正则表达式中是很有用的。如果不这样做的话,你必须使用两个反斜杠,类似 '(\d+)/(\d+)/(\d+)' 。
>>> m = datepat.match('11/27/2012abcdef')
>>> m
<_sre.SRE_Match object at 0x1005d27e8>
>>> m.group()
'11/27/2012'
>>>
如果你想精确匹配,确保你的正则表达式以 $ 结尾,就像这么这样:
>>> datepat = re.compile(r'(\d+)/(\d+)/(\d+)$')
>>> datepat.match('11/27/2012abcdef')
>>> datepat.match('11/27/2012')
<_sre.SRE_Match object at 0x1005d2750>
>>>
最后,如果你仅仅是做一次简单的文本匹配/搜索操作的话,可以略过编译部分,直接使用 re 模块级别的函数。比如:
>>> re.findall(r'(\d+)/(\d+)/(\d+)', text)
[('11', '27', '2012'), ('3', '13', '2013')]
>>>
但是需要注意的是,如果你打算做大量的匹配和搜索操作的话,最好先编译正则表达式,然后再重复使用它。模块级别的函数会将最近编译过的模式缓存起来,因此并不会消耗太多的性能,但是如果使用预编译模式的话,你将会减少查找和一些额外的处理损耗。
版权声明
本文为[巨輪]所创,转载请带上原文链接,感谢
https://my.oschina.net/jallenkwong/blog/4710738
边栏推荐
- C++ STL容器篇
- CCR炒币机器人:新冠肺炎加速了监管机构对CBDC的兴趣
- File初相识
- [论文阅读笔记] Network Embedding with Attribute Refinement
- GNU assembly basic mathematical equations multiplication
- 注册滴滴加不上车怎么办?要怎么处理?
- Only options request is sent, no post solution is sent
- 港股上市公司移卡收购创信众42.5%股权 谋划加快营销服务布局
- 【操作教程 】国标GB28181协议安防视频平台EasyGBS订阅功能介绍及开启步骤
- CSDN bug5: to be added
猜你喜欢

CCR炒币机器人:新冠肺炎加速了监管机构对CBDC的兴趣

csdn bug1:待加

工厂方法模式

jmeter接口测试--带有token的解决方法

The unscrupulous merchants increase the price of mate40, and Xiaomi is expected to capture more market in the high-end mobile phone market

想花钱速学互联网行业,大概花两三个月的时间,出来好找工作吗

Mongodb index management of distributed document storage database
![[paper reading notes] network embedding with attribute refinement](/img/71/760f29f8a13b366cf3bad4fb48bd63.jpg)
[paper reading notes] network embedding with attribute refinement

CCR coin robot: novel coronavirus pneumonia has accelerated the interest of regulators in CBDC.

使用call、apply和bind解决js中烦人的this,事件绑定时的this和传参问题
随机推荐
网络安全工程师演示:原来***是这样控制你的服务器的!(下)
Problems and solutions in configuring FTP server with FileZilla server
[elixir! #0073] beam 内置的内存数据库 —— ETS
[elixir! 0073] beam built-in memory database ETS
CSDN bug9: to be added
Use call, apply and bind to solve the annoying this in JS, this in event binding and parameter passing
走进C# abstract,了解抽象类与接口的异同
mac终端Iterm2支持rz和sz的解决方案
python pip命令的使用
坚持追查7年,近10亿美元比特币终被美国政府没收充公
如何看待阿里云成立新零售事业部?
An unsafe class named unsafe
[paper reading notes] community oriented attributed network embedding
监控系统选型,这篇不可不读!
The high pass snapdragon 875 has won the title of Android processor, but the external 5g baseband has become its disadvantage
Key layout of the Central Government: in the next five years, self-reliance and self-improvement of science and technology will be the priority, and these industries will be named
Getiservicemanager () source code analysis
csdn bug3:待加
Overview of the most complete anomaly detection algorithm in history
CentOS7本地源yum配置