文章目录
正则表达式
一、匹配类符号
一个符号对应一个字符
1.1 什么是正则表达式
- 一种处理字符串的工具
- 按指定规则自动处理字符串
- 在不同的编程语言中,正则的语法相同,但表示方式不同
python '正则表达式' js /正则表达式/
- re 模块是python内置的专门提供处理正则表达式函数的
import re
1.2 一般方法vs正则
感受一下
tel = input('请输入手机号:')
# 一般方法判断输入的tel是否是手机号
if len(tel) == 11:
for x in tel:
if not ('0' <= x <= '9'):
print('不合法')
else:
pass
# ...还有很多不写了
else:
print('不合法')
# 正则方法
result = re.fullmatch(r'1[3-9]\d{9}', tel)
print(result)
1.3 正则符号
1.3.1 普通字符
- 普通字符在正则表达式中表示这个符号本身
- fullmatch(正则表达式,字符串)
- 判断字符串是否符合指定规则
- 如果不符合,返回None
1.3.2 .
- 匹配一个任意字符
'a.b' - 匹配一个长度是3 的字符串,第一个字符是a,最后是b,中间随便一个字符
re_str = 'a.b'
result = re.fullmatch(re_str, 'a?b')
print(result) # <re.Match object; span=(0, 3), match='a?b'>
result = re.fullmatch(re_str, 'a??b')
print(result) # None
1.3.3 \d
- 在正则这里不是转义,就是一个正则符号
- 匹配一个任意数字
re_str = 'a\db'
# 匹配一个长度3 ,第一个字符a,最后一个字符b,中间一个任意数字字符
result = re.fullmatch(re_str, 'a0b')
print(result) # <re.Match object; span=(0, 3), match='a0b'>
re_str = 'a\d\d\d\d\db'
# 匹配一个长度5 ,第一个字符a,最后一个字符b,中间一个任意数字字符
result = re.fullmatch(re_str, 'a12345b')
print(result) # <re.Match object; span=(0, 7), match='a12345b'>
1.3.4 \s
- 匹配一个空白字符
- 空白字符:空格’ ‘、空行’\n’、制表’\t’
re_str = '\s\s\s'
result = re.fullmatch(re_str, '\n \t')
print(result) # <re.Match object; span=(0, 3), match='\n \t'>
1.3.5 \w
- 匹配一个字母、数字或下划线
- 但且ASCII码表以外的字符也都可以匹配
re_str = '\d\w\d'
result = re.fullmatch(re_str, '1嘿2')
print(result) # <re.Match object; span=(0, 3), match='1嘿2'>
result = re.fullmatch(re_str, '1+2')
print(result) # None
1.3.6 \D、\S
- 大写字母和小写字母反过来
- \D 匹配一个非数字字符
- \S 匹配一个非空白字符
1.3.7 字符集 []
- 匹配字符集中出现的任意一个字符
- 一个[]匹配一个字符
re_str = 'a[xy0]b'
# 长度3,第一个是a,最后是b,中间是x、y、0中的任意一个
result = re.fullmatch(re_str, 'axb')
print(result) # <re.Match object; span=(0, 3), match='axb'>
1.3.8 减号符 -
- 在[]中,-在两个字符之间出现表示范围
- 若不在两个字符之间,就表示’-'本身
- 前面的字符的编码值必须小于后面的编码值
re_str = 'a[Z-a]b'
# 长度3,中间为编码值在Z和a之间的任意一个字符
result = re.fullmatch(re_str, 'axb')
print(result) # None
result = re.fullmatch(re_str, 'a_b')
print(result) # <re.Match object; span=(0, 3), match='a_b'>
[1-9] - 一个数字字节
[a-z] - 一个小写字母
[A-Z] - 一个大写字母
[\u4e00-\u9fa5] - 一个中文字符
1.3.9 非 [^字符集]
- 在[]里
- 匹配一个不在字符集中的任意字符
- 只有放在最前面有效,放在其它地方都是’^'本身
1.3.10 忽略大小写 (?i)
- ‘(?i)正则表达式’,在正则表达式前面加上括号问号 i
- 给re模块中函数的flags赋值为 I(大写的i)
二、检测类符号
- 不影响字符串长度
- 在匹配成功后检查符号所在位置是否正确
2.1 \b
- 检测是否是单词边界
- 单词边界:可以将两个单词区分开来的字符
- 如空白、标点符号、字符串开头/结尾等
re_str = r'\ba[b-z]\b'
result = re.findall(re_str, 'dfas asdf fs4 asf az sdfe')
print(result) # ['az']
2.2 ^
- 检测字符串开头
2.3 $
- 检测是否是字符串结尾
三、匹配次数
3.1 +
- 至少1次
re_str = r'a+[b-z]'
result = re.findall(re_str, 'dfasaaaffs4asfazsdfe')
print(result) # ['as', 'aaaf', 'as', 'az']
3.2 *
- 至少0次
3.3 ?
- 两种情况
- 0次或1次
# 字符串是否是合法的整数
re_str = '[-+]?[1-9]\d*' # 但没有0
3.4 {}
- {N} 匹配N次
- {M,N} [M, N]次
- {M,} 至少M次
- {,N} 最多N次
3.5 贪婪、非贪婪
-
在匹配次数不确定时
-
匹配氛围贪婪和非贪婪两种
-
默认贪婪
-
贪婪:在能匹配成功的情况下,取最多的那种情况
-
非贪:在能匹配成功的情况下,取最少的那种情况
-
设置非贪婪,在不确定次数后面加**?**
-
爬虫一般非贪
贪婪 非贪婪
———————————————
+ +?
* *?
? ??
{M,N} {M,N}?
{M,} {M,}?
{,N} {,N}?
———————————————
re_str = 'a.+b'
print(re.findall(re_str, 'azbzzbzzzbzzzzbzzzzz'))
# ['azbzzbzzzbzzzzb']
re_str = 'a.+?b'
print(re.findall(re_str, 'azbzzbzzzbzzzzbzzzzz'))
# ['azb']
四、分组、分支
- 将正则表达式中的某部分用()看作一个整体
- 然后进行整体操作
4.1 分组 ()
4.1.1 整体操作
re_str = '(\d{2}[a-z]{3})+'
result = re.fullmatch(re_str, '32sdf45zsd66sde21sdf')
print(result) # <re.Match object; span=(0, 20), match='32sdf45zsd66sde21sdf'>
4.1.2 整体重复\M
- 重复前面第M个分组匹配到的内容
re_str = r'(\d{2})([a-z]{3})=\2\1'
result = re.fullmatch(re_str, '12abc=cba21')
print(result) # None
re_str = r'(\d{2})([a-z]{3})=\2\1'
result = re.fullmatch(re_str, '12abc=abc12')
print(result) # <re.Match object; span=(0, 11), match='12abc=abc12'>
4.2 分支 |
# 练习:匹配:abc后面三个数字或三个大写字母
re_str = 'abc(\d|[A-Z]){3}'
result = re.fullmatch(re_str, 'abc123')
print(result) # <re.Match object; span=(0, 6), match='abc123'>
result = re.fullmatch(re_str, 'abcJKL')
print(result) # <re.Match object; span=(0, 6), match='abcJKL'>
五、转义符号
5.1 \
- 在正则中有特殊意义的符号前加 \ 让这个符号的功能消失,表示符号本身
5.2 []
- 在[]中,除了-、^、\d之类
- 其它符号都表示符号本身
六、re模块
6.1 fullmatch(正则表达式,字符串)
- 字符串和正则表达式是否完全匹配
- 匹配返回匹配对象
- 不匹配返回None
6.2 match(正则表达式,字符串)
- 开头匹配
6.3 search(正则表达式,字符串)
- 第一个满足的子串
6.4 findall(正则表达式,字符串)
- 所有满足的子串
- 返回列表
- 如果正则表达式有分组,只返回分组里面的字符串
- 多个分组,列表里的每个元素是个元组
6.5 split(正则表达式,字符串)
- 将满足正则表达式的子串作为切割点
6.6 sub(正则表达式,str1,str2)
- 替换
- 将str2中满足的子串替换为str1