1. 用正则表达式查找文本模式
正则表达式,简称为 regex,是文本模式的描述方法。
1) 创建regex对象
Python中所有正则表达式的函都在re模块中,如果在使用时没有导入则会报错。向re.compile()传入一个正在表达式,它将返回一个Regex模式对象(或简称Regex对象)。
示例:
>>>phoneNumRegex = re.compile(r'\d\d\d-\d\d\d-\d\d\d\d')2) 匹配 Regex 对象
Regex 对象的search()方法查找传入的字符串,寻找该正则表达式的所有匹配。如果字符串中没有找到该正则表达式模式,search()方法将返回None。如果找到了该模式,search()方法将返回一个 Match 对象。Match 对象有一个 group()方法,它返回被查找字符串中实际匹配的文本。示例:
>>>phoneNumRegex = re.compile(r'\d\d\d-\d\d\d-\d\d\d\d')
>>> mo = phoneNumRegex.search('My number is 415-555-4242.')
>>> print('Phonenumber found: ' + mo.group())
Phone number found: 415-555-42422. 用正则表达式匹配更多模式
1) 利用括号分组
使用括号可以在正则表达式中创建分组,然后使用group()方法,就可以从一个分组中获得匹配的文本。正则表达式字符串中的第一对括号是第1 组,第二对括号是第 2 组,以此类推。向 group()方法传入整数 1 或 2……,就可以取得匹配文本的不同部分。向 group()方法传入 0 或不传入参数,将返回整个匹配的文本。如果想要一次就获取所有的分组,请使用groups()方法。示例:
>>>phoneNumRegex = re.compile(r'(\(\d\d\d\))(\d\d\d-\d\d\d\d)')
>>> mo = phoneNumRegex.search('My phone number is (415) 555-4242.')
>>> mo.group(1)
'(415)'
>>> mo.group(2)
'555-4242'2) 用管道匹配多个分组
字符|称为“管道”。希望匹配许多表达式中的一个时,就可以使用它。例如,正则表达式 r'Batman|Tina Fey'将匹配'Batman'或'Tina Fey'
如果 Batman 和 Tina Fey 都出现在被查找的字符串中,第一次出现的匹配文本,将作为 Match 对象返回。
如果需要匹配真正的管道字符,就用倒斜杠转义,即\|。
示例:
>>>heroRegex = re.compile (r'Batman|TinaFey')
>>> mo1 = heroRegex.search('Batman and Tina Fey.')
>>> mo1.group()
'Batman'
>>> mo2 = heroRegex.search('Tina Fey and Batman.')
>>> mo2.group()
'Tina Fey'3) 用问号实现可选匹配
字符?表明它前面的分组在这个模式中是可选的。示例:
>>> batRegex= re.compile(r'Bat(wo)?man')
>>> mo1 = batRegex.search('TheAdventures of Batman')
>>> mo1.group()
'Batman'
>>> mo2 = batRegex.search('The Adventures of Batwoman')
>>> mo2.group()
'Batwoman'4) 用星号匹配零次或多次
*(称为星号)意味着“匹配零次或多次”,即星号之前的分组,可以在文本中出现任意次。示例:
>>> batRegex= re.compile(r'Bat(wo)*man')
>>> mo1 = batRegex.search('TheAdventures of Batman')
>>> mo1.group()
'Batman'
>>> mo2 = batRegex.search('The Adventures of Batwoman')
>>> mo2.group()
'Batwoman'
>>> mo3 = batRegex.search('The Adventures of Batwowowowoman')
>>> mo3.group()
'Batwowowowoman'5) 用加号匹配一次或多次
*意味着“匹配零次或多次”,+(加号)则意味着“匹配一次或多次”。如果需要匹配真正的加号字符,在加号前面加上倒斜杠实现转义:\+。示例:
>>> batRegex= re.compile(r'Bat(wo)+man')
>>> mo1 = batRegex.search('TheAdventures of Batwoman')
>>> mo1.group()
'Batwoman'
>>> mo2 = batRegex.search('The Adventures of Batwowowowoman')
>>> mo2.group()
'Batwowowowoman'
>>> mo3 = batRegex.search('The Adventures of Batman')
>>> mo3 == None
True6) 用花括号匹配特定次数
如果想要一个分组重复特定次数,就在正则表达式中该分组的后面,跟上花括号包围的数字。
a) 如果只有一个数字n,表示出现n次。例如,正则表达式(Ha){3}将匹配字符串'HaHaHa',
b) 还可以指定一个范围,即在花括号中写下一个最小值、一个逗号和一个最大值。例如,正则表达式(Ha){3,5}将匹配'HaHaHa'、'HaHaHaHa'和'HaHaHaHaHa'。
c) 指定范围时,如果省略第一个值,表示从0开始,如果省略第二个值,表示不限定。
示例:
>>> haRegex= re.compile(r'(Ha){3}')
>>> mo1 = haRegex.search('HaHaHa')
>>> mo1.group()
'HaHaHa'
>>> mo2 = haRegex.search('Ha')
>>> mo2 == None
True3. 贪心和非贪心匹配
Python 的正则表达式默认是“贪心”的,这表示在有二义的情况下,它们会尽可能匹配最长的字符串。花括号的“非贪心”版本匹配尽可能最短的字符串,即在结束的花括号后跟着一个问号。示例:
>>>greedyHaRegex = re.compile(r'(Ha){3,5}')
>>> mo1 = greedyHaRegex.search('HaHaHaHaHa')
>>> mo1.group()
'HaHaHaHaHa'
>>> nongreedyHaRegex =re.compile(r'(Ha){3,5}?')
>>> mo2 = nongreedyHaRegex.search('HaHaHaHaHa')
>>> mo2.group()
'HaHaHa'4. findall()方法
Regex对象有一个findall()方法。作为 findall()方法的返回结果的总结,请记住下面两点:
如果调用在一个没有分组的正则表达式上,例如\d\d\d-\d\d\d-\d\d\d\d,方法findall()将返回一个匹配字符串的列表,例如['415-555-9999', '212-555-0000']。示例;
>>> phoneNumRegex = re.compile(r'\d\d\d-\d\d\d-\d\d\d\d') # has no groups
>>> phoneNumRegex.findall('Cell: 415-555-9999 Work: 212-555-0000')
['415-555-9999', '212-555-0000']如果调用在一个有分组的正则表达式上,例如(\d\d\d)-(\d\d\d)-(\d\d\d\d),方法 findall()将返回一个字符串的元组的列表(每个分组对应一个字符串),例如[('415','555', '1122'), ('212', '555', '0000')]。示例:
>>> phoneNumRegex = re.compile(r'(\d\d\d)-(\d\d\d)-(\d\d\d\d)') # has groups
>>> phoneNumRegex.findall('Cell: 415-555-9999 Work: 212-555-0000')
[('415', '555', '1122'), ('212', '555', '0000')]5. 字符分类
6. 建立自己的字符分类
可以用方括号自定义字符分类,示例;
>>> vowelRegex = re.compile(r'[aeiouAEIOU]')
>>> vowelRegex.findall('RoboCop eats baby food. BABY FOOD.')
['o', 'o', 'o', 'e', 'a', 'a', 'o', 'o', 'A', 'O', 'O']也可以使用短横表示字母或数字的范围。例如,字符分类[a-zA-Z0-9]将匹配所有小写字母、大写字母和数字。
在方括号内,普通的正则表达式符号不会被解释。这意味着,你不需要前面加上倒斜杠转义.、*、?或()字符。例如,字符分类将匹配数字 0 到 5 和一个句点。你不需要将它写成[0-5\.]。
通过在字符分类的左方括号后加上一个插入字符(^),就可以得到“非字符类”。非字符类将匹配不在这个字符类中的所有字符。
7. 插入字符和美元字符
^表明匹配必须发生在被查找文本开始处。$表示该字符串必须以这个正则表达式的模式结束。可以同时使用^和$,表明整个字符串必须匹配该模式。示例:
>>> wholeStringIsNum = re.compile(r'^\d+$')
>>> wholeStringIsNum.search('1234567890')
<_sre.SRE_Match object; span=(0, 10), match='1234567890'>
>>> wholeStringIsNum.search('12345xyz67890') == None
True
>>> wholeStringIsNum.search('12 34567890') == None
True
本文介绍了如何使用Python的正则表达式进行文本模式查找,包括基本语法、分组、匹配选项等,并通过实例展示了findall方法的应用。
1544

被折叠的 条评论
为什么被折叠?



