匹配单个字符
接下来的内容会跟着 这本书的内容,所以强烈建议感兴趣的朋友买一本。
学习使用正则表达式匹配一个或多个字符。
匹配单个字符
import re # 测试文本 text = """ hello, my name is Ben. Please visit my website at http://www.forta.com/ . """ # 正则表达式 regexp = r'Ben' # 编译 pattern = re.compile(regexp) # 匹配 rs = pattern.findall(text) print(rs) # 正则表达式 regexp = r'my' # 编译 pattern = re.compile(regexp) # 匹配 rs = pattern.findall(text) print(rs) ## 正则表达式是区分大小写的,但通常它的实现提供了可以忽略大小写的选项, ## 在 Python 中,它是由 flags 参数控制,输入 Re.I 即可 # 正则表达式 regexp = r'ben' # 编译 pattern = re.compile(regexp, re.I) # 匹配 r = pattern.search(text) print(r)
多个匹配
通常只匹配第一个结果,然后返回。 Python 的实现中,所以如果我们想要获取所有的匹配结果,那么就需要选择相应的方法了。这里简单介绍一下单个匹配和多个匹配的区别:
- match、search 匹配结果即返回,两者的区别在于 match 它是匹配文本的开头,而 search 匹配整个文本,直到找到结果,然后返回。
- findall、finditer 匹配所有结果返回,两者的区别在于 findall 以列表的形式返回所有匹配结果, findditer 以迭代器的形式返回。
import re # 测试文本 text = """ I love you yesterday and today. I love you yesterday and today. I love you yesterday and today. I love you yesterday and today. I love you yesterday and today. """ # 正则表达式 regexp = r'love' # 编译 pattern = re.compile(regexp) # 单个匹配 # match 匹配 m = pattern.match(text) if m: print("match: ", m.group())
else:
print("match() no match!")
# search 匹配
m = pattern.search(text)
if m:
print("search: ", m.group())
else:
print("search() no match!")
# 多个匹配
# findall 匹配
rs = pattern.findall(text)
if rs:
print("findall: ", rs)
else:
print("findall no matches!")
# finditer 匹配
rs = pattern.finditer(text)
if rs:
print("finditer", rs)
for r in rs:
print("finditer: ", r)
else:
print("finditer no matches!")
love 没有在开头,所以 match 无法匹配到。
字母的大小写问题
正则表达式是区别大小写的,所以 Ben 不匹配 ben。但是,大多数正则表达式的实现都支持不区分字母大小写的匹配操作。在 Python 的实现中,它是依靠参数 flags 来控制的,如果需要启用,则传入 re.I
或 re.IGNORECASE
。
from ast import pattern
import re
# 测试文本
text = """ hello, my name is ben. Please visit my website at http://www.forta.com/ . """
# 正则表达式
regexp = r'Ben'
# 编译 re.I 或 re.IGNORECASE
pattern = re.compile(regexp, re.I)
# 匹配
m = pattern.search(text)
if m:
print(m.group())
else:
print("No match")
匹配任意字符
前面的示例中的正则表达式匹配的都是静态文本,无法体现出正则表达式的威力。下面,我们一起来看看如何使用正则表达式去匹配不可预知的字符。
在正则表达式里,特殊字符(或字符集合)用来标示要搜索的东西。.
字符(英文句号)可以匹配任意单个字符。例如:正则表达式 c.t
可以匹配 cat
和 cot
或者其它符合形式的字母组合。
示例:
import re
# 测试文本
text = """ sales1.xls orders3.xls sales2.xls sales3.xls apac1.xls europe2.xls na1.xls na2.xls sa1.xls """
# 正则表达式
regexp = r'sales.'
# 编译
pattern = re.compile(regexp)
# 匹配
rs = pattern.findall(text)
if rs:
print(rs)
else:
print("No matches!")
正则表达式 sales.
可以匹配所有以 sales 开头,后面跟着任意一个字符的文件名。
.
字符可以匹配任意单个字符、字母、数字甚至是 . 字符本身:
import re
# 测试文本
text = """ sales.xls sales1.xls orders3.xls sales2.xls sales3.xls apac1.xls europe2.xls na1.xls na2.xls sa1.xls """
# 正则表达式
regexp = r'sales..'
# 编译
pattern = re.compile(regexp)
# 匹配
rs = pattern.findall(text)
if rs:
print(rs)
else:
print("No matches!")
这里多增加了一个 sales.xls,它也是可以被匹配到的。
在同一个正则表达式里允许使用多个 .
字符,它们既可以共同出现(..
将匹配连续的任意两个字符),也可以分别出现在模式的不同位置。
下面整个例子:把以 na 或 sa 开头的文件(不管它们后面跟着什么数字)找出来。
import re
# 测试文本
text = """ sales.xls sales1.xls orders3.xls sales2.xls sales3.xls apac1.xls europe2.xls na1.xls na2.xls sa1.xls """
# 正则表达式
regexp = r'.a.'
# 编译
pattern = re.compile(regexp)
# 匹配
rs = pattern.findall(text)
if rs:
print(rs)
else:
print("No matches!")
如果按行匹配,使用 match 方法可以避免这个问题,因为 match 方法就是从头开始匹配的。
这样做会多匹配很多其它的文件名,但是这不是我们所需要的。这里我们尝试在后面多加一个 .
来尝试一下:
import re
# 测试文本
text = """ sales.xls sales1.xls orders3.xls sales2.xls sales3.xls apac1.xls europe2.xls na1.xls na2.xls sa1.xls """
# 正则表达式
regexp = r'.a..'
# 编译
pattern = re.compile(regexp)
# 匹配
rs = pattern.findall(text)
if rs:
print(rs)
else:
print("No matches!")
这样做比上面更加糟糕了,因为我们想要匹配的是字符 .
,而不是任意字符。
匹配特殊字符
. 字符在正则表达式里面有特殊含义,如果模式需要匹配一个 .
,而不是要匹配任意字符,就需要对其进行转义。转义的方法很简单,在需要转义的字符前面加上,例如对于字符 .
的转义为 \.
。
\
是一个元字符(metacharacter,表示“这个字符有特殊含义,代表的不是字符本身”)。
注意:如果需要匹配的字符是 \
,那么需要使用它本身进行转义,即 \\
。
完整的匹配文件名:
import re
# 测试文本
text = """ sales.xls sales1.xls orders3.xls sales2.xls sales3.xls apac1.xls europe2.xls na1.xls na2.xls sa1.xls """
# 正则表达式
regexp = r'.a.\.'
# 编译
pattern = re.compile(regexp)
# 匹配
rs = pattern.findall(text)
if rs:
print(rs)
else:
print("No matches!")
这样我们就可以正确匹配到需要的文件名了(包含 . 字符)。
最后,在正则表达式上加上文件的扩展名 xls
,避免匹配到 sa3.doc
这样的文件名。
import re
# 测试文本
text = """ sales.xls sales1.xls orders3.xls sales2.xls sales3.xls apac1.xls europe2.xls na1.xls na2.xls sa1.xls """
# 正则表达式
regexp = r'.a.\.xls'
# 编译
pattern = re.compile(regexp)
# 匹配
rs = pattern.findall(text)
if rs:
print(rs)
else:
print("No matches!")
小结
正则表达式,也被称为模式。起始是一些由字符构成的字符串。这些字符可以是字面字符(普通字符)或元字符(有特殊含义的字符)。上面学习了,如何使用普通文本和元字符去匹配单个字符。 在正则表达式里,有特殊含义的字符序列总是以 \
字符开头。