1、概述
正则表达式(英语:Regular Expression,常简写为regex、regexp或RE),又称正则表示式、正则表示法、规则表达式、常规表示法,是计算机科学的一个概念。正则表达式使用单个字符串来描述、匹配一系列符合某个句法规则的字符串。
许多程序设计语言都支持利用正则表达式进行字符串操作。同样,在python中就内建了一个功能强大的正则表达式引擎。
我们在普通的操作中已经可以拼接追加甚至替换字符串等基本操作了,但是当我们需要进行字符串查找、一些以某几个字符开头的字符串查找、及只提取字符串中的数字,等等带有一定规则匹配的字符串,常规的操作就不是那么好处理了。
但是,通过使用正则表达式我们就可以很方便的进行操作,而且速度也很快。这也可理解为正则表达式的巨大作用。
运行正则表达式需要程序设计语言集成正则表达式引擎,只有在这个引擎上才可以解析正则表达式,Python编译环境就自动集成了此引擎,所以我们可以直接在python代码中使用正则表达式。
正则表达式长什么样?
表达式 | 描述 |
---|---|
\D | 匹配一个非数字字符。等价于 [^0-9],不是0到9的数字。 |
#.*$ | 匹配#这个字符串后的所有字符 |
z* | 匹配*号前面的子表达式零次或多次出现的字符串 |
更多的正则表达式的介绍可以参考此链接:正则表达式
在Python中如何使用正则表达式?
首先我们需要导入对应的模块。
import re
2、关键函数
本文主要用到了如下关键函数:
名称 | 描述 |
---|---|
re.match(pattern, string, flags=0) | 匹配到了正则表达式,就返回一个相应的 匹配对象 。 如果没有匹配,就返回 None 。无论是单行还是多行模式, re.match() 也只匹配字符串的开始位置,而不匹配每行开始 |
re.search(pattern, string, flags=0) | 扫描整个 字符串 找到匹配样式的第一个位置,并返回一个相应的 匹配对象。如果没有匹配,就返回一个 None ; |
re.sub(pattern, repl, string, count=0, flags=0) | 返回通过使用 repl 替换在 string 最左边非重叠出现的 pattern 而获得的字符串。 |
re.compile(pattern, flags=0) | 将正则表达式的样式编译为一个 正则表达式对象 (正则对象)。 |
re.finditer(pattern, string, flags=0) | pattern 在 string 里所有的非重复匹配,返回为一个迭代器 iterator 保存了 匹配对象 。 string 从左到右扫描,匹配按顺序排列。空匹配也包含在结果里。 |
re.split(pattern, string, maxsplit=0, flags=0) | 用 pattern 分开 string 。 如果在 pattern 中捕获到括号,那么所有的组里的文字也会包含在列表里。如果 maxsplit 非零, 最多进行 maxsplit 次分隔, 剩下的字符全部返回到列表的最后一个元素。 |
flags这个参数可以设置的值如下:
- .* 表示任意匹配除换行符(\n、\r)之外的任何单个或多个字符
- re.I 使匹配对大小写不敏感
- re.L 做本地化识别(locale-aware)匹配
- re.M 多行匹配,影响 ^ 和 $
- re.S 使 . 匹配包括换行在内的所有字符
- re.U 根据Unicode字符集解析字符。这个标志影响 \w, \W, \b, \B.
- re.X 该标志通过给予你更灵活的格式以便你将正则表达式写得更易于理解。
flags可以通过|符合并联多个。
其实上面这表看起来比较复杂,实际上在案例里面进行操作会更容易理解。
3、案例
import re
# 返回一个元组包含匹配(开始,结束) 的位置
print(re.match('www', 'www.baidu.com').span())
# re.match 只会从第一个位置开始匹配,如果没找到则直接返回None
print(re.match('c', 'www.baidu.com'))
line = "This is your life!"
# .* 表示任意匹配除换行符(\n、\r)之外的任何单个或多个字符
# re.I 使匹配对大小写不敏感
# re.L 做本地化识别(locale-aware)匹配
# re.M 多行匹配,影响 ^ 和 $
# re.S 使 . 匹配包括换行在内的所有字符
# re.U 根据Unicode字符集解析字符。这个标志影响 \w, \W, \b, \B.
# re.X 该标志通过给予你更灵活的格式以便你将正则表达式写得更易于理解。
matchObj = re.match(r'(.*) is (.*?) .*', line, re.M | re.I)
# 用are 来分组,group(1) 为左边的 Cats ,group(2) 为右边的 smarter
if matchObj:
print("matchObj.groups:", matchObj.groups())
print("matchObj.group:", matchObj.group())
print("matchObj.group(1):", matchObj.group(1))
print("matchObj.group(2):", matchObj.group(2))
else:
print("no match!")
# 搜索
print(re.search('www', 'www.baidu.com').span())
print(re.search('com', 'www.baidu.com').span())
line = "This is your life!"
searchObj = re.search(r'(.*) is (.*?) .*', line, re.M | re.I)
if searchObj:
print("searchObj.group() : ", searchObj.group())
print("searchObj.group(1) : ", searchObj.group(1))
print("searchObj.group(2) : ", searchObj.group(2))
else:
print("Nothing found!!")
line = "This is your life!"
matchObj = re.match(r'is', line, re.M | re.I)
if matchObj:
print("match --> matchObj.group() : ", matchObj.group())
else:
print("No match!!")
matchObj = re.search(r'is', line, re.M | re.I)
if matchObj:
print("search --> matchObj.group() : ", matchObj.group())
print("search --> matchObj.group() : ", matchObj.group()[0]) # 代表is中的i
print("search --> matchObj.group() : ", matchObj.group()[1]) # 代表is中的s
else:
print("No match!!")
phoneStr = "135-000-1234 # 电话号码格式化!"
num = re.sub(r'#.*$', "", phoneStr) # $匹配输入字符串结尾的位置。
print("手机号码:", num)
# 移除非数字的内容
num = re.sub(r'\D', "", phoneStr) # \D 匹配一个非数字字符。等价于 [^0-9],不是0到9的数字。
print("电话号码 : ", num)
pattern = re.compile(r'\d+') # 用于匹配至少一个数字
m = pattern.match('abc12defghijk34lmno') # 查找头部,没有匹配
print(m)
m = pattern.match('abc12defghijk34lmno', 2, 10) # 从'e'的位置开始匹配,没有匹配
print(m)
m = pattern.match('abc12defghijk34lmno', 3, 10) # 从'1'的位置开始匹配,正好匹配
print(m)
print(m.group()) # 方法用于获得一个或多个分组匹配的字符串,当要获得整个匹配的子串时,可直接使用 group() 或 group(0);
print(m.start()) # 方法用于获取分组匹配的子串在整个字符串中的起始位置(子串第一个字符的索引),参数默认值为 0;
print(m.end()) # 方法用于获取分组匹配的子串在整个字符串中的结束位置(子串最后一个字符的索引+1),参数默认值为 0
print(m.span()) # 方法返回 (start(group), end(group))。
pattern = re.compile(r'\d+') # 查找数字
result1 = pattern.findall('data 123 google 456')
result2 = pattern.findall('run88data123google456', 0, 10)
print(result1)
print(result2)
it = re.finditer(r"\d+","2112a322bc23j13f32") #在字符串中找到正则表达式所匹配的所有数字组,并把它们作为一个迭代器返回。
for match in it:
print (match.group() )
res=re.split('\W+', 'data, data, data.')
print(res)
res=re.split('(\W+)', ' data, data, data.')
print(res)
res=re.split('\W+', ' data, data, data.', 1)
print(res)
res=re.split('z*', 'z1z2z3zhello world') # 对于一个找不到匹配的字符串而言,split 不会对其作出分割
print(res)
输出结果:
(0, 3)
None
matchObj.groups: ('This', 'your')
matchObj.group: This is your life!
matchObj.group(1): This
matchObj.group(2): your
(0, 3)
(10, 13)
searchObj.group() : This is your life!
searchObj.group(1) : This
searchObj.group(2) : your
No match!!
search --> matchObj.group() : is
search --> matchObj.group() : i
search --> matchObj.group() : s
手机号码: 135-000-1234
电话号码 : 1350001234
None
None
<_sre.SRE_Match object; span=(3, 5), match='12'>
12
3
5
(3, 5)
['123', '456']
['88', '1']
2112
322
23
13
32
['data', 'data', 'data', '']
['', ' ', 'data', ', ', 'data', ', ', 'data', '.', '']
['', 'data, data, data.']
['', '1', '2', '3', 'hello world']
对应的关键函数必须要通过案例才能更好的掌握它。
4、总结
在java里面也支持正则表达式,是类似的,正则表达式可以更好的处理字符串操作。
对于正则表达式的语法规则有很多,可以记住一些常用的,其他的可以用到时再查。
一定要自己动手写一写Demo才能更好的去理解并应用。