正则表达式(RegularExpression, re)
- 是一个计算机科学的概念
- 用于使用单个字符串来描述,匹配一系列匹配某个句法规则的字符串
- 常用来检索,替换某些模式的文本
正则表达式的写法
.(点号): 匹配任意一个字符,除了\n[]: 匹配中括号中列举的字符,例如[LY]\d: 表示任意一个数字,0-9\D: 表示非数字,即不是数字就可以\s: 匹配空白,即空格,tab键\S: 除了空白以外的字符\w: 单词字符,即a-z, A-Z, 0-9, _\W: 非单词字符*: 表示前面内容重复零次或者多次+: 前面内容重复至少一次?: 前面出现的内容零次或者一次{m,n}: 允许前面内容出现最少m次,最多n次^: 匹配字符串的开始$: 匹配字符串的结尾\b: 匹配单词的边界(): 对正则表达式内容进行分组,从第一个括号开始,编号逐渐增大
示例:
# 验证一个数字
^\d$
# 必须有一个数字,最少一位
^\d+$
# 只能出现数字,且位数为5-10位
^\d{5,10}$
# 注册者输入年龄,要求16岁以上,99岁以下
^[1-9][0-9]$
# 只能输入英文字符和数字
^[A-Za-z0-9]+$
# 验证QQ号码
^[1-9][0-9]{4,11}$
\A: 只匹配字符串开头,\Aabcd,则abcd\Z: 仅匹配字符串末尾,abcd\Z,abcd|: 左右任意一个(?P<name>...): 分组,除了原来的编号再制定一个别名,(?P<id>12345){2},1234512345(?P=name): 引用分组
re 模块
re.match(re_exp): 从开始查看是否能跟定义的正则相匹配result.group: 如果匹配数据成功,可以使用group来提取数据- 案例01, 案例代码是以函数进行区分,每个函数对应某个知识点,看下面的知识点对应具体函数理解就好
import re
def fun_1():
s = "I love wangxiaojing"
# 匹配是否跟wangxiaojing表白过
rst = re.match("wangxiaojing love", "wangxiaojing love me")
r = rst.group()
print(type(r))
print(r)
def fun_2():
# 匹配任意一个字符
rst = re.match(".", "9")
print(rst.group())
rst = re.match(".", "B")
print(rst.group())
rst = re.match("w", "Wang")
# 匹配为空
# print(rst.group())
rst = re.match("[wW]", "wang")
print(rst.group())
rst = re.match("[0123456789]", "89years")
print(rst.group())
# 匹配两位数字或者一位数字
rst = re.match("[0123456789]{1,2}", "89years")
print(rst.group())
# 匹配至少一位数字
rst = re.match("[0123456789]+", "809years")
print(rst.group())
def fun_3():
'''匹配字符'''
rst = re.match("[i]+", "i love wangxiaojing")
print(rst.group())
rst = re.match("\w+", "i love 3th wangxiaojing")
print(rst.group())
def fun_4():
dir = "C:\\a\\b\\c.txt"
print("DIR={0}".format(dir))
rst = re.match("C:\\\\a", dir)
print(rst.group())
rst = re.match(r"C:\\a", dir)
print(rst.group())
def fun_5():
rst = re.match("[1-9]?\d", "9")
print(rst.group())
rst = re.match("[1-9]?\d", "19")
print(rst.group())
rst = re.match("[1-9]?\d", "09")
print(rst.group())
rst = re.match("[1-9]?\d$", "09")
# 匹配为空
# print(rst.group())
rst = re.match("[1-9]?\d|\d+$", "09")
print(rst.group())
rst = re.match("[1-9]?\d$|\d+$", "09")
print(rst.group())
# 匹配邮箱
rst = re.match("\w{4,30}@163\.com", "wangdapeng@163.com")
print(rst.group())
# 匹配邮箱
rst = re.match("\w{4,30}@(163|126|qq)\.com", "wangdapeng@126.com")
print(rst.group())
def fun_6():
s = "i love wangxiaojing and zhangmingmin and lihua"
# search查找的结果只能是一个
rst = re.search("o", s)
print(rst.group())
rst = re.findall("[oi]", s)
print(type(rst))
print(rst)
rst = re.sub("[oi]", "8", s)
print(type(rst))
print(rst)
print(s)
fun_6()
re中原生字符串问题
- 字符串中会包含转义字符
- 在re中,转义字符会带来一些麻烦,能不能尽量减少转义字符的出现
- 在字符串前使用r字符,表示后面字符串是原始字符串,不需要转义,例如
r'c:\wk\readme.txt' - 案例01-fun_4
正则的分组表示
|: 匹配左右任意一个表达式(ab): 将括号中字符作为一个分组\num: 引用分组num匹配到的字符串(?P<name>): 分组起一个别名,其中P是大写(?P=name): 引用别名为name分组匹配到的字符串- 案例01中 fun_5函数
re 模块的一般使用步骤如下:
- 使用
compile()函数将正则表达式的字符串形式编译为一个 Pattern 对象 - 通过 Pattern 对象提供的一系列方法对文本进行匹配查找,获得匹配结果,一个 Match 对象
- 最后使用 Match 对象提供的属性和方法获得信息,根据需要进行其他的操作
re常用函数
group([group1, …])方法用于获得一个或多个分组匹配的字符串,当要获得整个匹配的子串时,可直接使用group()或group(0)start([group])方法用于获取分组匹配的子串在整个字符串中的起始位置(子串第一个字符的索引),参数默认值为 0end([group])方法用于获取分组匹配的子串在整个字符串中的结束位置(子串最后一个字符的索引 +1),参数默认值为 0span([group])方法返回(start(group), end(group))
正则的其他用法
- 案例01, fun_6
search: 查找其中一个内容findall: 查找所有内容sub: 查找替换,返回替换之后的内容,原来被替换的内容不变
匹配代码
import re
p = re.compile(r'\d+')
m = p.match("one12twothree34four")
print(m)
m = p.match("one12twothree34four", 3, 10)
print(m)
print(m[0])
m.start(0) # 参数是组号
m.end(0)
# 第二个例子
p = re.compile(r'([a-z]+) ([a-z]+)', re.I) # re.I表示忽略大小写,两个中间有空格
m = p.match('I really love wangxiaojing ')
print(m)
print(m.group(0))
m.start(0)
m.span(0)
m.group(1)
m.group(2)
m.group(0) # 整个匹配子串
m.groups() # 全部的打印出来
查找代码
search(str[, pos[, endpos]])findallfinditer
import re
p = re.compile(r'\d+')
m = p.search('one12twothree34four')
print(m.group())
p = re.compile('\d+')
m = p.search('hello 123456 7890')
print(m.group())
# findall
rst = p.findall("hello 12345 67890")
print(rst)
sub替换
sub(rep1, str[,count])
import re
p = re.compile(r'(\w+) (\w+)') # \w是字符
s = "hello 123 and hello 456"
rst = p.sub(r'hello world', s)
print(rst)
rst = p.sub(r'\2 \1', s)
print(rst)
def func(m):
return 'gaga' + m.group(2)
rst = p.sub(func, s)
print(rst)
rst = p.sub(func, s, 1)
print(rst)
匹配中文
- 中文主要表示范围是
[\u4e00-\u9fa5],不包括全角标点
import re
title = u'你好 世界, hello moto'
p = re.compile(r'[\u4e00-\u9fa5]+')
rst = p.findall(title)
print(rst)
贪婪和非贪婪
- 尽可能多的匹配,
* - 非贪婪,
? - 默认贪婪
import re
title = u'<div>name</div><div>age</div>'
p1 = re.compile(r"<div>.*</div>")
p2 = re.compile(r"<div>.*?</div>")
m1 = p1.search(title)
print(m1.group())
m2 = p2.search(title)
print(m2.group())