正则表达式
步骤
测试程序位于 http://regexpal.com/
1.用 import re 导入正则表达式模块。
2.用 re.compile()函数创建一个 Regex 对象(记得使用原始字符串)。
3.向 Regex 对象的 search()方法传入想查找的字符串。它返回一个 Match 对象。
4.调用 Match 对象的 group()方法,返回实际匹配文本的字符串。
模式
正则表达式符号复习
?匹配零次或一次前面的分组。
*匹配零次或多次前面的分组。
+匹配一次或多次前面的分组。
{n}匹配 n 次前面的分组。
{n,}匹配 n 次或更多前面的分组。
{,m}匹配零次到 m 次前面的分组。
{n,m}匹配至少 n 次、至多 m 次前面的分组。
{n,m}?或*?或+?对前面的分组进行非贪心匹配。
^spam 意味着字符串必须以 spam 开始。
spam$意味着字符串必须以 spam 结束。
.匹配所有字符,换行符除外。
\d、\w 和\s 分别匹配数字、单词和空格。
\D、\W 和\S 分别匹配出数字、单词和空格外的所有字符。
[abc]匹配方括号内的任意字符(诸如 a、b 或 c)。
[^abc]匹配不在方括号内的任意字符。
利用括号分组
向 group() 匹配对象方法传入整数 1 或 2,就可以取得匹配文本的不同部分。向 group()方法传 入 0 或不传入参数,将返回整个匹配的文本
*正则表达式字符串中的第一对括号是第 1 组。第二对括号是第 2 组
*例子
*>>> 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'
传递给 re.compile()的原始字符串中,\(和\)转义字符将匹配实际的括号字符。
### 用管道匹配多个分组:字符|称为“管道”
*希望匹配许多表达式中的一个时,就可以使用它
*例子
*>>> heroRegex = re.compile (r'Batman|Tina Fey') >>> mo1 = heroRegex.search('Batman and Tina Fey.') >>> mo1.group()
'Batman'
>>> mo2 = heroRegex.search('Tina Fey and Batman.') >>> mo2.group()
'Tina Fey'
用问号实现可选匹配
你可以认为?是在说,“匹配这个问号之前的分组零次或一次”。 如果需要匹配真正的问号字符,就使用转义字符\?。
*字符?表明它前面的分组在这个模式中是可选的
*例子
*>>> batRegex = re.compile(r'Bat(wo)?man')
>>> mo1 = batRegex.search('The Adventures of Batman') >>> mo1.group()
'Batman'
>>> mo2 = batRegex.search('The Adventures of Batwoman') >>> mo2.group()
'Batwoman'
* >>> phoneRegex = re.compile(r'(\d\d\d-)?\d\d\d-\d\d\d\d') >>> mo1 = phoneRegex.search('My number is 415-555-4242') >>> mo1.group()
'415-555-4242'
>>> mo2 = phoneRegex.search('My number is 555-4242') >>> mo2.group()
'555-4242'
用星号匹配零次或多次
**(称为星号)意味着“匹配零次或多次”,即星号之前的分组,可以在文本中出现任意次。它可以完全不存在,或一次又一次地重复
*例子
*>>> batRegex = re.compile(r'Bat(wo)*man') >>> mo1 = batRegex.search('The Adventures >>> mo1.group()
'Batman'
>>> mo2 = batRegex.search('The Adventures >>> mo2.group()
'Batwoman'
>>> mo3 = batRegex.search('The Adventures >>> mo3.group()
'Batwowowowoman'
用加号匹配一次或多次
**意味着“匹配零次或多次”,+(加号)则意味着“匹配一次或多次”。
*例子
*>>> batRegex = re.compile(r'Bat(wo)+man') >>> mo1 = batRegex.search('The Adventures >>> mo1.group()
'Batwoman'
>>> mo2 = batRegex.search('The Adventures >>> mo2.group()
'Batwowowowoman'
>>> mo3 = batRegex.search('The Adventures >>> mo3 == None
True
用花括号匹配特定次数
*如果想要一个分组重复特定次数,就在正则表达式中该分组的后面,跟上花括 号包围的数字
贪心和非贪心匹配
*正则表达式默认是“贪心”的,这表示在有二义的情况下,它们会尽 可能匹配最长的字符串
*例子
*Ha){3,5}可以匹配 3 个、4 个或 5 个实例,你可能 会想,为什么在前面花括号的例子中,Match 对象的 group()调用会返回'HaHaHaHaHa', 而不是更短的可能结果。毕竟,'HaHaHa'和'HaHaHaHa'也能够有效地匹配正则表达 式(Ha){3,5}。
*花括号的“非贪心”版本匹配尽可能最短的字符串,即在 结束的花括号后跟着一个问号。
*例子
*>>> 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'
插入字符和美元字符
*正则表达式的末尾加上美元符号($),表示该字符串必 须以这个正则表达式的模式结束。可以同时使用^和$
通配字符
*(句点)字符称为“通配符”。它匹配除了换行之外的所有 字符
*例子
*>>> atRegex = re.compile(r'.at')
>>> atRegex.findall('The cat in the hat sat on the flat mat.') ['cat', 'hat', 'sat', 'lat', 'mat']
用点-星匹配所有字符
*句点字符表示“除换行外所有单个字符”,星号字符表示“前 面字符出现零次或多次”。
### 用句点字符匹配换行
*句点字符匹配所有字符,包括换行字符
*通过传入 re.DOTALL 作为 re.compile()的第 二个参数,可以让句点字符匹配所有字符,包括换行字符。
*例子
*>>> noNewlineRegex = re.compile('.*')
>>> noNewlineRegex.search('Serve the public trust.\nProtect the innocent. \nUphold the law.').group()
'Serve the public trust.'
>>> newlineRegex = re.compile('.*', re.DOTALL)
>>> newlineRegex.search('Serve the public trust.\nProtect the innocent.
\nUphold the law.').group()
'Serve the public trust.\nProtect the innocent.\nUphold the law.
方法
findall()方法
*返回结果
*1.如果调用在一个没有分组的正则表达式上,例如\d\d\d-\d\d\d-\d\d\d\d,方法 findall()将返回一个匹配字符串的列表,例如['415-555-9999', '212-555-0000']。
*2.如果调用在一个有分组的正则表达式上,例如(\d\d\d)-(\d\d\d)-(\d\d\d\d),方 法 findall()将返回一个字符串的元组的列表(每个分组对应一个字符串),例如[('415', '555', '1122'), ('212', '555', '0000')]。
用 sub()方法替换字符串
Regex 对象的 sub()方法需要传入两个参数。第一个参数是一个字符串,用于取代发现的匹 配。第二个参数是一个字符串,即正则表达式。sub()方法返回替换完成后的字符串。
字符分类
*缩写字符分类
*\w \W \s \S
*任何字母、数字或下划线字符(可以认为是匹配“单词”字符)
*除字母、数字和下划线以外的任何字符
*空格、制表符或换行符(可以认为是匹配“空白”字符)
*除空格、制表符和换行符以外的任何字符
*正则表达式\d+\s\w+匹配的文本有一个或多个数字(\d+),接下来是一个空白字 符(\s),接下来是一个或多个字母/数字/下划线字符(\w+)。findall()方法将返回所有匹 配该正则表达式的字符串,放在一个列表中。