目录
正则表达式:
match()函数:
search()函数:
findall()函数:
正则表达式的参数:
表示字符范围的参数:
表示字符出现的次数的参数:
表示同一类字符的参数:
贪婪和非贪婪模式:
或和组:
sub()和complie()方法:
正则表达式
正则表达式(Regular Expression,re)是一种用于对字符串类型数据 进行高效的搜索、替换的操作。
其主要的匹配字符串的函数有三种:match(), search(),findall()
函数 | 匹配范围 | 返回结果 | 常见用途 |
---|---|---|---|
match() | 字符串起始位置 | 匹配的对象 或 None | 验证字符串是否以特定字符开头 |
search() | 整个字符串 | 第一个匹配的对象 或 None | 查找字符串中是否存在某个字符 |
findall() | 整个字符串 | 所有匹配的字符串 或 元组列表 | 提取文本中所有符合条件的内容 |
match()函数:
1.
import re
message = '张三、李四、王五、赵六'
result = re.match('张三',message) #从参数2中查找满足参数1的内容
print(result)
运行结果:
<re.Match object; span=(0, 2), match='张三'>
解析:re.match()
从字符串起始位置匹配正则表达式。此处 “张三” 位于message
开头,匹配成功,返回包含匹配位置(span=(0,2)
)和匹配内容的Match
对象。
2.
import re
message = '张三、李四、王五、赵六'
result = re.match('三',message) #起始位置匹配不成功的话,就返回none
print(result)
运行结果:
None
解析:re.match()
仅从字符串开头匹配。message
开头是 “张”,而非 “三”,匹配失败,返回None
。
search()函数:
import re
message = '张三、李四、王五、赵六、王五'
result = re.search('王五',message)
print(result)
运行结果:
<re.Match object; span=(6, 8), match='王五'>
解析:re.search()
在字符串任意位置查找第一个匹配的项。第一个 “王五” 位于索引 6-8 的位置,因此返回该位置的匹配对象。
findall()函数:
import re
message = '张三、李四、王五、赵六、王五'
result = re.findall('王五',message)#从参数2中查找满足参数1的所有内容
print(result)
运行结果:
['王五', '王五']
解析:re.findall()
返回所有匹配的内容,以列表形式呈现。message
中出现两次 “王五”,因此列表包含两个元素。
正则表达式的参数:
表示字符范围的参数:
[abc]:字符集合匹配,即匹配 abc 中的 任意一个字符。
[a-z]:范围匹配,即匹配指定范围内的 任意一个字符。
import re
message = 'Python93,C87,Java63,C++88'
result_1 = re.search('[cn]',message)
result_2 = re.findall('[0-9]',message)
result_3 = re.findall('[cn][0-9]',message) # 匹配字母c或n后接数字的组合
print(result_1,result_2,result_3)
运行结果:
<re.Match object; span=(5, 6), match='n'>
['9', '3', '8', '7', '6', '3', '8', '8'] ['n9']
解析:
[cn]
匹配字母c
或n
,message
中第一个符合的是Python
中的n
(索引 6)。[0-9]
匹配所有数字,提取出字符串中所有单个数字。[cn][0-9]
匹配c
或n
后接数字的组合,仅Python93
中的n9
符合。
表示字符出现的次数的参数:
符号 | 含义 | 示例与等价形式 |
---|---|---|
* | 匹配前面的子表达式任意次(≥0 次)。 | ab* 可匹配 "a", "ab", "abb" 等。 |
+ | 匹配前面的子表达式至少一次(≥1 次)。 | ab+ 可匹配 "ab", "abb",但不匹配 "a"。 |
? | 匹配前面的子表达式零次或一次(0 或 1 次)。 | ab? 可匹配 "a" 或 "ab"。 |
^ | 匹配输入字符串的开始位置。 | ^Hello 仅匹配以 "Hello" 开头的字符串。 |
$ | 匹配输入字符串的结束位置。 | world$ 仅匹配以 "world" 结尾的字符串。 |
{n} | 精确匹配前面的子表达式 n 次(n 为非负整数)。 | a{3} 仅匹配 "aaa"。 |
{n,} | 至少匹配前面的子表达式 n 次(n 为非负整数)。 | a{2,} 可匹配 "aa", "aaa" 等。 |
{n,m} | 最少匹配 n 次且最多匹配 m 次(n ≤ m,且均为非负整数)。 | a{1,3} 可匹配 "a", "aa", "aaa"。 |
示例1:
import re
message = 'da2a7ddbre77yifed777ttt3fefd7777b'
result = re.findall('[a-z]*[0-9][a-z]',message)
print(result)
result = re.findall('[a-z]+[0-9][a-z]',message)
print(result)
result = re.findall('[a-z]?[0-9][a-z]',message)
print(result)
运行结果:
['da2a', '7d', '7y', '7t', 'tt3f', '7b']
['da2a', 'ttt3f']
['a2a', '7d', '7y', '7t', 't3f', '7b']
解析:正则表达式[a-z]*[0-9][a-z]
表示:
[a-z]*
:0 个或多个小写字母;[0-9]
:1 个数字;[a-z]
:1 个小写字母。
匹配结果为包含 “数字前后有字母” 的片段。
示例2:
import re
phone_num = input("请输入您的手机号码:")
result = re.findall('^1[0-9]{10}$',phone_num)
print(result)
运行结果(输入13155558888
时):
['13155558888']
解析:正则^1[0-9]{10}$
验证手机号:
^1
:以 1 开头;[0-9]{10}
:紧跟 10 个数字;$
:结束符(确保无多余字符)。
匹配成功返回手机号列表,失败返回空列表。
错入输入无法匹配:
如果去掉 "$" ,就不再有输入位数限制:(即匹配足够的数字后停止)
示例3:
import re
QQ_number = input("请输入您的QQ号:")
result = re.match('[1-9][0-9]{4,10}$',QQ_number)
print(result)
运行结果(输入123456
时):
<re.Match object; span=(0, 6), match='123456'>
解析:正则[1-9][0-9]{4,10}$
验证 QQ 号:
[1-9]
:首位不为 0;[0-9]{4,10}
:后续 4-10 个数字(总长度 5-11 位)。
re.match()
从开头匹配,符合则返回匹配对象,否则返回None
。
示例4:
import re
use_name = input("请输入您的用户名:")
result = re.findall('^[A-Za-z_][A-Za-z0-9_]{7,}$',use_name)
print(result)
运行结果(输入User_1234
时):
['User_1234']
解析:正则验证用户名规则:
- 首位为字母或下划线;
- 后续为字母、数字或下划线,且总长度≥8 位。
匹配成功返回用户名列表,否则返回空列表。
错误输入无法匹配:
表示同一类字符的参数:
元字符 | 描述 | 等价于 |
---|---|---|
\d | 匹配一个数字类字符 | [0-9] |
\D | 匹配一个非数字类字符(^ 在中括号中表示 “非”) | [^0-9] |
\s | 匹配任何不可见字符,包括空格、制表符、换页符等 | [\f\n\r\t\v] |
\S | 匹配任何可见字符 | [^\f\n\r\t\v] |
\w | 匹配包括下画线的任何单词字符 | [A-Za-z0-9_] |
\W | 匹配任何非单词字符 | [^A-Za-z0-9_] |
\b | 匹配一个单词的边界,即单词和空格间的位置 | |
\B | 匹配非单词边界 | |
\f | 匹配一个分页符 | |
\n | 匹配一个换行符 | |
\r | 匹配一个 Enter 键符 | |
\t | 匹配一个制表符 | |
\v | 匹配一个垂直制表符 | |
. | 匹配除 “\n” 和 “\r” 之外的任何单个字符 |
示例1:
import re
use_name = input("请输入您的用户名:")
result = re.findall('^[A-Za-z_]\w{7,}$',use_name)
print(result)
运行结果(输入User_1234
时):
['User_1234']
解析:\w
任何单词字符等价于[A-Za-z0-9_]
示例2:
import re
message = 'verb very never every aer_'
result = re.findall(r'\w+er\B',message)
print(result)
运行结果:
['ver', 'ver', 'ever', 'aer']
解析:
\w+er
:匹配以er
结尾的单词片段;
\B
:非单词边界(即er
后紧跟其他字符,不是空格或结尾)。
示例3:
import re
message = 'verb very never every'
result = re.findall('.e',message)
print(result)
运行结果:
['ve', 've', 'ne', 've', ' e', 've']
解析:.
匹配任意字符(除换行、回车),'e'
匹配字母e
,因此.e
匹配 “任意字符 + e” 的组合。
贪婪和非贪婪模式:
贪婪模式:
尝试匹配尽可能多的字符,只要满足表达式要求都会匹配最多的字符
非贪婪模式:
一旦满足表达式要求就不再继续匹配。在次数限制操作符后面加上“?”可以将匹配模式转换为非贪婪模式。
示例1:
import re
message = 'ccc739134792hdccc1'
result = re.findall('ccc\d+',message)
print(result)
运行结果:
['ccc739134792', 'ccc1']
解析:\d是数字类字符,+是>=1次。为贪婪模式,匹配尽可能多的数字。
示例2:
import re
message = 'ccc739134792hd'
result = re.findall('ccc\d+?',message)
print(result)
运行结果:
['ccc7']
解析:\d是数字类字符,+是>=1次,?是0次或1次,三者结合后意思是匹配 一个数量类字符。为非贪婪模式
如果去掉加号:
或和组:
示例1:
或:符合两种情况的匹配
import re
message = 'verb very never every'
result = re.findall('\w+ev|\w+ry',message)
print(result)
运行结果:\w包括下画线的任何单词字符
['very', 'nev', 'every']
示例2:
将()中的表达式定义为组,并且将匹配这个表达式的字符保存到一个临时区域,即捕获匹配的内容
import re
message = 'verb very never every'
result = re.findall("e(.+)(.)r",message)
print(result)
运行结果:
[('rb very never ev', 'e')]
解析:()
表示分组,e(.+)(.)r
匹配:
- 以
e
开头,以r
结尾; - 第一个分组
(.+)
:匹配e
和r
之间的多个字符; - 第二个分组
(.)
:匹配r
前的单个字符。
sub()和complie()方法:
示例1:
re.sub()
用于在字符串中查找匹配正则表达式的部分,并替换为指定的内容
import re
content ='dh932hf9f934hfnf39d'
content = re.sub('\d','0',content)
print(content)
运行结果:
dh000hf0f000hfnf00d
解析:re.sub('\d','0',content)
将字符串中所有数字(\d
)替换为0
,非数字字符保持不变。
示例2:
re.compile()
用于 预编译正则表达式,提高多次匹配时的效率(避免重复解析正则表达式)。
import re
contentl ='2020 12 15 12:00'
pattern = re.compile('\d{2}:\d{2}')
print(pattern.findall(contentl))
运行结果:
['12:00']
解析:re.compile('\d{2}:\d{2}')
编译正则表达式(匹配 “两位数字:两位数字” 的时间格式),再通过pattern.findall()
从字符串中提取所有符合格式的内容,此处仅12:00
符合。