正则表达式
什么是正则表达式
- 描述祖字符串排列的一套规则. 可以按照需要, 找到某一类符合某种格式的信息.
正则表达式基础知识
原子
- 普通字符作为原子
- 非打印字符作为原子, 所谓非打印字符, 即在字符串中用于格式控制的符号, 比如换行符(‘\n’)等等.
- 通用字符作为原子:
- \w 匹配任意一个字母, 数字, 下划线
- \W 匹配除字母, 数字和下划线意外的任意一个字符
- \d 匹配任意一个十进制数
- \D 匹配除了十进制数以外的任意一个其他字符
- \s 匹配任意一个空白字符
- \S 匹配除空白字符以外的任意一个其他字符
- 原子表, 下面详细叙述
原子表
- 用于定义一组地位平等的原子, 然后匹配的时候会取该原子表中的任意一个原子进行匹配
- [xyz] 表示x,y,z 均可匹配
- [^xyz] 表示除了x,y,z 其他均满足表达式
元字符
- 所谓元字符, 就是正则表达式中具有一些特殊含义的字符, 比如重复N次前面的字符等.
符号 |
含义 |
符号 |
含义 |
. |
匹配除了换行符意外的任意字符 |
^ |
匹配字符串的开始位置 |
$ |
匹配字符串的结束位置 |
* |
匹配0,1或者多次前面的原子 |
? |
匹配0次或者1次前面的原子 |
+ |
匹配1次或者多次前面的原子 |
{n} |
前面的原子恰好出现n此 |
{n,} |
前面的原子至少出现n次 |
{n,m} |
前面的原子出现n到m次 |
\ |
|
模式选择符 |
() |
模式单元符 |
|
- 含义多次提到前面的字符, 意思就是: x* 表示x可以出现任意次.
边界限制元字符
- ^xyz 表示必须以xyz开头
- xyz$ 表示必须以xyz结尾
限定符
- x.*y 表示x,y之间可以有任意长度的任意字符.
- cd{2} 表示cdd
- cd{2,4} 表示c后面有2~4个d
模式选择符
使用模式选择符, 可以设置多个模式, 匹配时, 可以从中选择任意一个模式匹配. 比如:
- “python|php” 表示python和php均满足条件
模式单元符
可以将一些原子组成一个原子. 举个例子
- xy{2,} 表示 y 可以出现2次以上
- 而(xy){2,} 表示 xy 这个整体出现两次以上
模式修正
所谓模式修正, 即不改变正则表达式的情况下, 通过模式修正符改变正则表达式的含义, 从而实现匹配结果的调整.
符号 |
含义 |
符号 |
含义 |
I |
匹配时忽略大小写 |
M |
多行匹配 |
L |
做本地化识别匹配 |
U |
根据Unicode字符集解释字符 |
S |
让.匹配包括换行符. 即用了该模式修正之后, “.”就可以匹配任意字符了 |
|
实例:
import re try: pattern = "python" string = "PYTHOn" result1 = re.search(pattern,string,re.I) result2 = re.search(pattern,string) print("使用修正符%s"%result1) print("如果不使用%s"%result2) except Exception as e: print(e)
|
运行结果:
使用修正符<_sre.SRE_Match object; span=(0, 6), match='PYTHOn'> 如果不使用None
|
贪婪模式与懒惰模式
先来看看Python中贪婪和懒惰的定义
- 贪婪: 尽可能多的匹配
- 懒惰: 尽可能少的匹配, 采取就近匹配的原则, 让匹配结果更为准确.
import re try: pattern1 = "p.*y" pattern2 = "p.*?y" string = "abcdefphp345pythony_py" result1 = re.search(pattern1,string) result2 = re.search(pattern2,string) print(result1) print(result2) except Exception as e: print(e)
|
结果:
<_sre.SRE_Match object; span=(6, 22), match='php345pythony_py'> <_sre.SRE_Match object; span=(6, 14), match='php345py'>
|
- 使用贪婪模式,: .*
- 转换为懒惰模式: 相应的 .*后面加上 ?
正则表达式常见函数
re.match()函数
想要从元字符串的起始位置匹配一个模式?
match(pattern, string, flags=0)
|
- flags 是对应的标志位, 可以放模式修正符等信息.
import re string = 'apythonbcpythonoo' pattern = '.python.' result1 = re.match(pattern,string) result2 = re.match(pattern,string).span() print(result1) print(result2)
|
<_sre.SRE_Match object; span=(0, 8), match='apythonb'> (0, 8)
|
re.search() 函数
一个例子看清 search函数 和 match函数的区别:
import re string = 'asdadasapythonbcpythonoo' pattern = '.python.' result1 = re.match(pattern,string) result2 = re.search(pattern,string) print('使用match:%s'%result1) print('使用search:%s'%result2)
|
使用match:None 使用search:<_sre.SRE_Match object; span=(7, 15), match='apythonb'>
|
- 可以看到, match只从开始匹配, 而search是从整个string寻找. 如果开头不匹配, match一定是None, 而只要后面包括pattern, 那么search就会返回目标位置.
findall() 函数
上面两个函数只是匹配第一个成功匹配的结果, 那么如果把所有符合的内容全部找到呢?
- 使用re.compile() 对正则表达式进行预编译
- 编译后, 使用findall() 根据正则表达式找到匹配的全部结果.
import re string = 'asdadasapythonbcpythonoo' pattern = re.compile('.python.') result = pattern.findall(string) print(result)
|
re.sub() 函数
想根据正则表达式来实现替换某些字符串
- sub(pattern, repl, string, count=0, flags=0)
- pattern: 正则表达式
- rep: 要替换成的字符串
- string: 源字符串
- count: 最多替换count次, 默认全部替换.
- flags: 标志位, 用于放模式修正符
import re
string = 'Tom and tim love Jerry' pattern = "T.m" rep = 'Hox' result = re.sub(pattern,rep,string,flags=re.I) print(result)
|
常见实例解析
import re
pattern = "[a-zA-Z]+://[\S]+[.com|.cn]" string = "dasdfasdfasdf http://www.baidu.comdasdfasdf" result = re.search(pattern,string) print(result)
|
<_sre.SRE_Match object; span=(14, 34),match='http://www.baidu.com'>
|
- 分析:
- URL格式: 协议 :// 域名 .com/.cn
- 协议可以是任意长度(大于1)的字母的组合, 所以用 [a-zA-Z]+ 表示
- 中间的域名不能使用空格以外的任意字符串, 所以用 \S+ 表示\
- 最后用 模式选择符 表示 .com 和 .cn
实例2: 匹配电话号码
import re
string = "Hox's python number is 0351-5207923, 这是我很小的时候家里>的固话号码"
pattern = "\d{3}-\d{8}|\d{4}-\d{7}" result = re.search(pattern,string) print(result)
|
<_sre.SRE_Match object; span=(23, 35), match='0351-5207923'>
|
实例3: 匹配电子邮件地址
import re
string = "Hox's email is 213162855@seu.edu.cn" pattern = '\w+([.+-]\w+)*@\w+([.-]\w+)*\.\w+([.-]\w+)*' result = re.search(pattern,string) print(result)
|
<_sre.SRE_Match object; span=(15, 35),match='213162855@seu.edu.cn'>
|