1 正则表达式概述
1.1 什么是正则表达式
正则表达式:Regular Expression,是一些由特殊的字符和符号组成的字符串,主要用来进行高级的文本匹配、搜索、替换等功能操作。
正则表达式是一个独立的技术,python中提供了re模块来支持正则表达式
1.2 第一个正则表达式
import re
target = "hello, email@qq.com regexp in python with regular on expression"
reg = r"l"
print(re.findall(reg, target))
2 正则表达式操作语法
2.1 基本语法
2.1.1 基本正则语法
匹配字符符号 | 描述 | 案例 |
---|---|---|
literal | 匹配文本字面值 | foo |
re1/re2 | 匹配正则表达式 re1或者re2 | foo/bar |
^ | 匹配目标字符串开头位置 | ^Dear |
$ | 匹配目标字符串结束位置 | py$ |
. | 匹配任意一个字符(\n 除外) | h.llo |
? | 匹配任意一个字符出现0次/1次 | foo? |
+ | 匹配任意一个字符出现1次/n次 | foo+ |
* | 匹配任意一个字符出现0次/n次 | foo* |
{m} | 匹配任意一个字符按 m 次 | foo{m} |
{m,} | 匹配任意一个字符出现至少 m 次 | foo{m,} |
{m,n} | 匹配任意一个字符出现 m~n 次 | foo{2,5} |
[0-9] | 匹配任意一个 0~9 之间的数字 | [0-9]{11} |
[^0-9] | 匹配任意一个非数字字符 | |
[3-6] | 匹配任意一个 3~6 之间的数字 | |
[0-10] | 匹配 00 或者 10 两个数字 | |
[a-z] | 匹配任意一个小写字母 | |
[A-Z] | 匹配任意一个大写字母 | |
[a-zA-Z] | 匹配任意一个字母 | |
[a-zA-Z0-9_] | 匹配任意字母/数字/下划线 | |
(...) | 匹配分组正则表达式 | (0-9){3}-(0-9){4} |
2.1.2 正则表达式:元字符
符号 | 描述 | 示例 |
---|---|---|
\d | 匹配任意一个[0-9]的数字 | data\d+.txt |
\D | 匹配任意一个非数字字符 | info_\D+.log |
\s | 匹配任意一个空白字符[\n\t\r\v\f] | <a\s+href= |
\S | 匹配任意一个非空白字符 | \S{6} |
\w | 匹配任意一个字母/数字/下划线 | \w{8,18} |
\W | 匹配任意一个非字母/数字/下划线 | |
\b | 匹配任意一个单词的边界 | \bfood\b |
\ | 转义字符,可以用于匹配正则中用到的字符 | \, ., *, +,... |
2.1.3 正则表达式:零宽断言
符号 | 描述 |
---|---|
(?reg) | 特殊标记参数 |
(?:reg) | 匹配不用保存的分组 |
(?Preg) | 匹配到分组结果命名 name |
(?P=name) | 匹配(?Preg)前的文本 |
(?#comment) | 注释 |
(?=reg) | 正向前视断言(零宽断言) |
(?!reg) | 负向前视断言(零宽断言) |
(?<=reg) | 正向后视断言(零宽断言) |
(?<!reg) | 负向后视断言(零宽断言) |
(?(id/name)Yre1/Nre2) | 条件断言分组 |
3 正则语法案例
3.1 基本正则语法
"""
FILE : 正则表达式语法操作
DATETIME: 2018/10/18 11:22
AUTHOR : chenliang
DESC :
"""
import re
s = '''Are you new to Django or to programming? This is the place to start!
From scratch: Overview | Installation
Tutorial: Part 1: Requests and responses | Part 2: Models and the admin site
| Part 3:
Views and templates | Part 4: Forms and generic views | Part 5: Testing |
Part 6:
Static files | Part 7: Customizing the admin site
Advanced Tutorials: How to write reusable apps | Writing your first patch
for Django123_
'''
# 1 基本语法
reg1 = r"to"
print(re.findall(reg1, s))
# ['to', 'to', 'to', 'to', 'to', 'to', 'to']
# 2 或者匹配
reg2 = r"Django|part"
print(re.findall(reg2, s))
# ['Django', 'Django']
# 3 开头匹配
reg3 = r"^Are"
print(re.findall(reg3, s))
# ['Are']
# 4 结尾匹配
reg4 = r"Django123_$"
print(re.findall(reg4, s))
# ['Django123_']
# 5 认识字符匹配
reg5 = r"Ho."
print(re.findall(reg5, s))
# ['How']
# 6 范围匹配?
reg6 = r"pr?"
print(re.findall(reg6, s))
# ['pr', 'p', 'p', 'p', 'p', 'p', 'p']
# 7 范围匹配+
reg7 = r"pr+"
print(re.findall(reg7, s))
# ['pr']
# 8 范围匹配*
reg8 = r"pr*"
print(re.findall(reg8, s))
# ['pr', 'p', 'p', 'p', 'p', 'p', 'p']
# 9 范围匹配{m}
reg9 = r"l{2}"
print(re.findall(reg9, s))
# ['ll']
# 10 范围匹配{m, n}
reg10 = r"l{1,3}"
print(re.findall(reg10, s))
# ['l', 'll', 'l', 'l', 'l', 'l', 'l', 'l']
# 11 范围匹配{0-9}
reg11 = r"[0-9]+"
print(re.findall(reg11, s))
# ['1', '2', '3', '4', '5', '6', '7', '123']
# 12 范围匹配[a-z]
reg12 = r"[a-z]{10}"
print(re.findall(reg12, s))
# ['programmin', 'nstallatio', 'ustomizing']
# 13 范围匹配[a-zA-Z0-9_]
reg13 = r"[a-zA-Z0-9_]{10}"
print(re.findall(reg13, s))
# ['programmin', 'Installati', 'Customizin', 'Django123_']
3.2 元字符语法
"""
FILE : 元字符语法
DATETIME: 2018/10/19 11:52
AUTHOR : chenliang
DESC :
"""
import re
s = """
Django Community 11445 people, 164 countries, 3854 packages and projects.
"""
# 1 \d
reg1 = r"\d+"
print(re.findall(reg1, s))
# ['11445', '164', '3854']
# 2 \s
reg2 = r"\s+"
print(re.findall(reg2, s))
# ['\n', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '\n']
# 3 \b
reg3 = r"\ban+"
print(re.findall(reg3, s))
# ['an']
# 4 \w
reg4 = r"\w{5}"
print(re.findall(reg4, s))
# ['Djang', 'Commu', '11445', 'peopl', 'count', 'packa', 'proje']
3.3 分组查询语法
"""
FILE : 分组查询语法
DATETIME: 2018/10/19 11:57
AUTHOR : chenliang
DESC :
"""
import re
s = '''
<img src="./images/1.jpg"/>
<img src="./images/2.jpg"/>
<img src="./images/3.jpg"/>
<img src="./images/4.jpg"/>
<img src="./images/5.jpg"/>
'''
reg = r'<img\s+src="(.*)"/>'
res = re.finditer(reg, s)
for r in res:
print(r.group())
print(r.group(1))
"""
result:
<img src="./images/1.jpg"/>
./images/1.jpg
<img src="./images/2.jpg"/>
./images/2.jpg
<img src="./images/3.jpg"/>
./images/3.jpg
<img src="./images/4.jpg"/>
./images/4.jpg
<img src="./images/5.jpg"/>
./images/5.jpg
"""
3.4 零宽断言语法
"""
FILE : 零宽断言
DATETIME: 2018/10/19 12:01
AUTHOR : chenliang
DESC :
"""
import re
# 目标字符串
s = 'aahelloworldbbhellojerryjerryup'
# 1 正向前视断言
reg1 = r".{2}hello(?=world)"
res = re.finditer(reg1, s)
for r in res:
print(r.group()) # aahello
# 2 负向前视断言
reg2 = r".{2}hello(?!world)"
res = re.finditer(reg2, s)
for r in res:
print(r.group()) # bbhello
# 3 正向后视断言
reg3 = r".(?<=hello)jerry.{2}"
res = re.finditer(reg3, s)
for r in res:
print(r.group()) # ojerryje
# 4 负向后视断言
reg4 = r"(?<!hello)jerry.{2}"
res = re.finditer(reg4, s)
for r in res:
print(r.group()) # jerryup
贪婪匹配和懒惰匹配
"""
FILE : 贪婪匹配和懒惰匹配
DATETIME: 2018/10/19 12:10
AUTHOR : chenliang
DESC :
"""
import re
target_str = "<div>hello</div><p>world</p><div>regular expression</div>"
# 正则表达式:贪婪模式
reg = re.compile(r"<div>.*</div>")
# 查询数据
res = reg.search(target_str)
print(res.group())
# <div>hello</div><p>world</p><div>regular expression</div>
# # 正则表达式:非贪婪模式
reg = re.compile(r"<div>.*?</div>")
# 查询数据
res = reg.search(target_str)
print(res.group())
# <div>hello</div>
3 python中的正则
3.1 为什么使用正则表达式
正则表达式本身就是对于字符串的高效处理,尽管字符串本身也内置了一些操作函数,但是相对于较为复杂的需求,通过正则表达式的操作更加的灵活并且效率更高
正则表达式在程序中的主要应用,有以下几个方面
匹配:测试一个字符串是否符合正则表达式语法,返回True或者False
获取:从目标字符串中,提取符合正则表达式语法的字符数据
替换:在目标字符串中查询符合正则语法的字符,并替换成指定的字符串
分割:按照符合正则表达式的语法字符对目标字符串进行分割
3.2 创建正则表达式对象的方式
隐式创建:通过一个普通字符串,直接创建正则表达式;要求:必须通过re模块的函数调用才能正常编译执行
import re
# 创建一个正则表达式
reg = r"\bfoo\b"
# 从目标字符串中提取数据
result = re.findall(reg, target_str)
显式创建:通过内建函数compile()编译创建一个正则表达式对象;要求:可以通过调用该类型的方法,完成字符的操作
import re
target_str = "helloworldhelloregexp"
# 1 函数
reg = r"(?<=hello).{3}"
print(re.findall(reg, target_str))
# 对象
reg2 = re.compile(r"(?=hello).{3}")
print(reg2.findall(target_str))
3.3 常用方法
常用方法 | 描述 |
---|---|
re.findall(s, start, end) | 返回(指定位置)查询到结果内容的列表 |
re.finditer(s, start, end) | 返回(指定位置)查询到结果匹配对象的生成器 |
re.search(s, start, end) | 返回(指定位置)第一次查询到的匹配对象 |
re.match(s, start, end) | 返回(指定位置)从第一个字符串匹配到的结果对象 |
re.sub(s, r, c) | 使用r替换字符串中的所有匹配的数据,c是替换次数 |
re.subn(s, r, c) | 使用r替换字符串中所有匹配的数据,c是替换次数 |
re.split(s, m) | 使用正则表达式拆分字符串,m是拆分次数 |
代码示例
import re
target_str = "helloworldhellojerryhelloregularexpression"
reg = r"hello"
# findall()
print(re.findall(reg, target_str))
# ['hello', 'hello', 'hello']
# finditer()
res = re.finditer(reg, target_str)
for s in res:
print(s.group())
"""
hello
hello
hello
"""
# search()
res = re.search(reg, target_str)
print(res)
# <re.Match object; span=(0, 5), match='hello'>
# match()
res = re.match(reg, target_str)
print(res)
# <re.Match object; span=(0, 5), match='hello'>
# sub
res = re.sub(reg, "**", target_str)
print(res)
# **world**jerry**regularexpression
# subn
res = re.subn(reg, "**", target_str)
print(res)
# ('**world**jerry**regularexpression', 3)
# split
res = re.split(reg, target_str)
print(res)
# ['', 'world', 'jerry', 'regularexpression']