# 一.正则表达式匹配符号
## 1.什么是正则表达式
# 正则表达式是一种可以让字符串处理变得很简单的工具
# 正则表达式就是通过各种正则符号来描述字符串的规则
# 在不同的编程语言中,正则的语法是相同的,但是表示方式不同:python - '正则表达式' , js - /正则表达式/
## 2.正则符号
### 1) 普通字符 - 普通字符在正则表达式中表示这个符号本身
from re import fullmatch
re_str = 'abc'
result = fullmatch(re_str, 'abc')
print(result)
### 2) . 匹配一个任意字符
"""
'a.b' - 匹配一个长度是3的字符串,第一个字符是a,最后字符是b, 中间一个是任意字符
"""
re_str = 'a.b'
result = fullmatch(re_str, 'akb')
print(result)
result = fullmatch(re_str, 'a+b')
print(result)
result = fullmatch(re_str, 'x+b')
print(result)
result = fullmatch(re_str, 'a++b')
print(result)
re_str = 'xy..'
result = fullmatch(re_str, 'xyj就')
print(result)
### 3) \d - 匹配一个任意数字
re_str = 'a\db'
result = fullmatch(re_str, 'a9b')
print(result)
result = fullmatch(re_str, 'a0b')
print(result)
result = fullmatch(re_str, 'axb')
print(result)
re_str = 'a\d\d\d'
result = fullmatch(re_str, 'a238')
print(result)
### 4) \s - 匹配一个空白字符
re_str = 'abc\s123'
result = fullmatch(re_str, 'abc 123')
print(result)
result = fullmatch(re_str, 'abc\t123')
print(result)
result = fullmatch(re_str, 'abc\n123')
print(result)
result = fullmatch(re_str, 'abc123')
print(result)
### 5) \w(了解) - 匹配一个字母、数字或者下划线(ASCII码表以外的字符都可以匹配)
re_str = '\d\w\d'
result = fullmatch(re_str, '2看8')
print(result)
### 6) \D - 匹配任意一个非数字字符 \S - 匹配任意一个非空白字符
re_str = 'a\Db'
result = fullmatch(re_str, 'a9b')
print(result)
result = fullmatch(re_str, 'a就b')
print(result)
re_str = '\d\S\d'
result = fullmatch(re_str, '2=8')
print(result)
result = fullmatch(re_str, '2 8')
print(result)
### 7) [字符集] - 匹配字符集中出现的任意一个字符
"""
注意:a.一个[]只能匹配一个字符
b.在[]中可以将-放在两个字符之间表示范围,但是-前面的字符的编码值必须小于后面的字符的编码值
c. 在[]中-只有在两个字符之间才有特殊意义,如果在最前面或者最后面就表示-本身
[a1+] - 匹配字符a或者字符1或者字符+
[\dxy] 、 [x\dy] 、 [xy\d] - 匹配一个任意数字或者x或者y
[1-9] - 匹配1到9的任意一个数字字符
[a-z] - 匹配任意一个小写字母
[A-Z] - 匹配任意一个大写字母
[a-zA-Z]
[\u4e00-\u9fa5] - 匹配任意一个中文字符
下列写法都支持:
[a-z+=/]
[1a-z2]
[2-8a-z]
[\da-z]
"""
re_str = 'a[xy0]b'
result = fullmatch(re_str, 'a0b')
print(result)
re_str = 'a[\dmn]b'
result = fullmatch(re_str, 'amb')
print(result)
re_str = 'a[1-9]b'
result = fullmatch(re_str, 'a9b')
print(result)
### 8) [^字符集] - 匹配不在字符集中的任意一个字符
"""
[^abc] - 匹配除了a、b、c以外的任意字符
[^\d] - 匹配任意一个非数字字符
[^a-z] - 匹配任意一个非小写字母的字符
"""
re_str = '\d[^abc]\d'
print(fullmatch(re_str, '3好6'))
re_str = '\d[abc^]\d'
print(fullmatch(re_str, '3^6'))
# 二、检测类符号
## 1. \b - 检测是否是单词边界 \B - 检测是否不是单词边界
from re import fullmatch, findall
re_str = r'abc,\b123'
result = fullmatch(re_str, 'abc,123')
print(result)
re_str = r'\b\d\d\s\babc'
result = fullmatch(re_str, '89 abc')
print(result)
re_str = r'\d\d\B'
str1 = '啥时间89sksj28jsk 09 会计89, jss,85,结束素数10'
result = findall(re_str, str1)
print(result)
## 2. ^ - 检测字符串开头
re_str = '^\d\d\d'
result = fullmatch(re_str, '892')
print(result)
re_str = '^\d\d\d'
result = findall(re_str, '8890shsh892快捷键920js110ss334')
print(result)
## 3.$ - 检测是否是字符串结尾
re_str = '\d\d\d$'
result = findall(re_str, '8890shsh892快捷键920js110ss334')
print(result)
# 三、匹配次数
## 1. + - 一次或多次(至少一次)
"""
a+ - 字符a出现一次或者多次
\d+ - 匹配一次或者多次任意数字字符
.+ - 匹配一次或者多次任意字符
[xyz]+
"""
re_str = 'xa+y'
result = fullmatch(re_str, 'xay')
print(result)
result = fullmatch(re_str, 'xaay')
print(result)
result = fullmatch(re_str, 'xaaaaaaaay')
print(result)
re_str = 'x\d+y'
print(fullmatch(re_str, 'x2y'))
print(fullmatch(re_str, 'x2823y'))
re_str = '1[xyz]+1'
print(fullmatch(re_str, '1x1'))
print(fullmatch(re_str, '1xx1'))
print(fullmatch(re_str, '1xy1'))
## 2. * - 匹配0次或多次(任意次数)
re_str = 'xa*y'
print(fullmatch(re_str, 'xy'))
## 3. ? - 匹配0次或一次
print(fullmatch('0?abc', '0abc'))
re_str = '[-+]?[1-9]\d*'
## 4.
print(fullmatch('a{4}\d{3}', 'aaaa345'))
print(fullmatch('a{2,4}\d{2,}[a-z]{,3}', 'aaaa887hjk'))
##5.贪婪和非贪婪(重要!)
re_str = r'a.+?b'
print(findall(re_str, 'amnmb123blkb计算机上'))
re_str = r'a.+b'
print(findall(re_str, 'amnmb123lk计算机上'))
# 四、分组和分支
## 1. () - 分组
from re import fullmatch
"""
分组就是将正则表达式中的某部分用()括起来看成一个整体,然后进行整体的操作。
在正则表达式中一个()表示一个分组
1)整体操作
'(\d{2}[a-z]{3})+'
2)整体重复
\M - 重复前面第M个分组匹配到的内容
"""
print(fullmatch('(\d{2}[a-z]{3})+', '23hsk90nmb'))
re_str = r'(\d{3})ab\1'
print(fullmatch(re_str, '789ab789'))
print(fullmatch(re_str, '112ab112'))
re_str = r'(\d{3})([a-z]{2})=\1{2}'
print(fullmatch(re_str, '341ab=341341'))
re_str = r'(\d{3})([a-z]{2})=\2\1'
print(fullmatch(re_str, '341ab=ab341'))
## 2. | - 分支
re_str = 'abc\d{3}|abc[A-Z]{3}'
print(fullmatch(re_str, 'abcMKS'))
re_str = 'abc(\d{3}|[A-Z]{3})'
print(fullmatch(re_str, 'abc987'))
## 3.转义符号
re_str = '\d{2}\.[a-z]{3}'
print(fullmatch(re_str, '89.hsk'))
print(fullmatch(re_str, '89Mhsk'))
re_str = '\d\+'
print(fullmatch(re_str, '8+'))
re_str = '\d[+*|?$^()-]\d'
print(fullmatch(re_str, '2)8'))
# re模块
## 1.fullmatch(正则表达式, 字符串) - 判断字符串和正则表达式是完全匹配, 如果可以匹配返回匹配对象,否则返回None
## 2.match(正则表达式, 字符串) - 判断字符串的开头是否和正则匹配,如果可以匹配返回匹配对象,否则返回None
from re import fullmatch, match, search, findall, split, sub
re_str = '\d{3}'
print(fullmatch(re_str, '892'))
print(match(re_str, '923海兽祭祀shsjjj'))
## 3.search(正则表达式, 字符串) - 获取字符串中第一个满足正则表达式的子串,如果可以匹配返回匹配对象,否则返回None
print(search(re_str, 'jsjh892sjjdjjs2'))
## 4.findall(正则表达式, 字符串) - 获取字符串中所有满足正则表达式的子串,返回一个列表
print(findall(re_str, 'jsj 2839计算机282开始了11234,hss273681kl892p'))
re_str = '\d{3}[a-z]'
print(findall(re_str, 'jsj 2839计算机282开始了11234,hss273681kl892p'))
re_str = '(\d{3})[a-z]'
print(findall(re_str, 'jsj 2839计算机282开始了11234,hss273681kl892p'))
re_str = '\d{2}[a-z]{2}'
print(findall(re_str, 'jsj89op就是789mn-=s函数56mn82是否879、'))
re_str = '\d{2}([a-z]{2})'
print(findall(re_str, 'jsj89op就是789mn-=s函数56mn82是否879、'))
re_str = '(\d{2})([a-z]{2})'
print(findall(re_str, 'jsj89op就是789mn-=s函数56mn82是否879、'))
## 5.split(正则表达式, 字符串) - 将字符串中所有满足正则表达式的子串作为切割点,对字符串进行切割
print(split('[a-z]+', '你好akslb江苏省a护具b==='))
## 6.sub(正则表达式, 字符串1, 字符串2) - 将字符串2中满足正则表达式的子串都替换成字符串1
print(sub('\d+', '+', '就是90JJ是239jsj函数2海事局'))