正则表达式
2017-12-30 22:11
239 查看
1 正则表达式是什么
2 在Python中需要通过正则表达式对字符串进行匹配的时候,可以使用一个模块,名字为re
2.1 re模块的使用过程:
3 匹配单个字字符 功能
.匹配任意1个字符(除了\n)
[ ]匹配[ ]中列举的字符
\d匹配数字,即0-9
\D匹配非数字,即不是数字
\s匹配空白,即 空格,tab键
\S匹配非空白
\w匹配单词字符,即a-z、A-Z、0-9、_
\W匹配非单词字符
4 匹配多个字符
字符 功能
* 匹配前一个字符出现0次或者无限次,即可有可无 \d* 等价于\d{0,}
+ 匹配前一个字符出现1次或者无限次,即至少有1次 \d+ 等价于\d{1,}
? 匹配前一个字符出现1次或者0次,即要么有1次,要么没有 \d?等价于\d{0,1}
{m} 匹配前一个字符出现m次
{m,n} 匹配前一个字符出现从m到n次配开头和结尾
6 匹配分组
7 re模块函数
7.1
8 re模块高级用法
9 贪婪模式与非贪婪模式
Python中字符串前面加上 r 表示原生字符串
Regular Expression, 又称规则表达式。 正则表达式,就是用事先定义好的一些特定字符(组合),组成一个“规则字符串”,这个“规则字符串”用来描述了一种字符串的匹配模式(pattern)。 正则的作用:可以用来检查一个串是否含有某种数据、将匹配的数据替换或者取出
2 在Python中需要通过正则表达式对字符串进行匹配的时候,可以使用一个模块,名字为re
2.1 re模块的使用过程:
#coding=utf-8 # 导入re模块 import re # 使用match方法进行匹配操作 result = re.match(正则表达式,要匹配的字符串) # 如果上一步匹配到数据的话,可以使用group方法来提取数据 result.group() # 如果没有匹配 则result是None result = re.search(正则表达式,要匹配的字符串) # 如果上一步匹配到数据的话,可以使用group方法来提取数据 result.group() # 如果没有匹配 则result是None
2.2re模块示范例子:
#coding=utf-8 import re result = re.search(r"itcast","itcast.cn") result.group() result = re.match(r"itcast","itcast.cn") result.group( 运行结果为:itcast
3 匹配单个字字符 功能
.匹配任意1个字符(除了\n)
[ ]匹配[ ]中列举的字符
\d匹配数字,即0-9
\D匹配非数字,即不是数字
\s匹配空白,即 空格,tab键
\S匹配非空白
\w匹配单词字符,即a-z、A-Z、0-9、_
\W匹配非单词字符
4 匹配多个字符
字符 功能
* 匹配前一个字符出现0次或者无限次,即可有可无 \d* 等价于\d{0,}
+ 匹配前一个字符出现1次或者无限次,即至少有1次 \d+ 等价于\d{1,}
? 匹配前一个字符出现1次或者0次,即要么有1次,要么没有 \d?等价于\d{0,1}
{m} 匹配前一个字符出现m次
{m,n} 匹配前一个字符出现从m到n次配开头和结尾
字符 功能 ^ 匹配字符串开头,开始位置, 虽然match自带匹配开始的属性 但是为了正则的语义完整 建议也加上^ $ 匹配字符串结尾,结束位置 匹配的是结束位置 而不是数据
6 匹配分组
字符 功能 | 匹配左右任意一个表达式 (ab) 将括号中字符作为一个分组 \num 引用分组num匹配到的字符串 (?P<name>) 分组起别名 (?P=name) 引用别名为name分组匹配到的字符串 详解: 目的 -- 在正则中使用() 将感兴趣的数据从整体中提取出来 放到分组存储 等整体匹配成功返回的结果对象中 .group(分组编号)就可以获取对应分组中数据了 group(0) == group() 就是正则表达式整体匹配的结果 用户的分组编号从1开始 () 表示匹配数据并放入分组 .group(分组编号)就可以获取对应分组中数据了 | 表示匹配|左边或者右边的正则表达式 (|) 表示匹配分组中| 左边或者右边的表达式 并且放入分组中 eg:<html>hh</html> --- <标签名>数据</标签名> 判断左边的标签和右边的标签名是否一致 如果一致则提取中的数据 引用分组的方式 目的 在正则的某个位置想要使用前面某个分组的数据进行匹配 使用形式: \分组编号 <html><h1>www.itcast.cn</h1></html> re.match(r"(<\w+)><(\w+)>(.*)</\2></\1>","<html><h1>www.baidu.com</h1></html>").group(1) 有名分组 在匹配分组的时候 使用一个名字 而不直接使用下标 设置分组名称 (?P<name>) 引用某个名称的分组的数据 (?P=name)
7 re模块函数
7.1
match() 从头开始匹配 如果某个字符不能满足匹配规则 将匹配失败 返回None 直到匹配完成 将匹配结果放入匹配结果对象中,从匹配结果对象中获取到匹配结果,matchobj.group() result = re.match(正则, 数据) if result: print(result.group()) else: print("匹配失败")
7.2
search() 从头开始查找 如果某个字符不能满足匹配规则 将继续往后面查找 并尝试继续匹配 如果查找完 都没有匹配上 则返回None 如果匹配成功 将匹配结果放入匹配结果对象中,从匹配结果对象中获取到匹配结果,matchobj.group() result = re.search(正则,数据) if result: print(result.group()) else: print("匹配失败") eg:匹配出文章阅读的次数 #coding=utf-8 import re ret = re.search(r"\d+", "阅读次数为 9999") ret.group() 运行结果:'9999'
8 re模块高级用法
8.1
findall(正则,数据) 查找数据中所有 符合正则规则的 数据 通过列表返回 eg:需求:统计出python、c、c++相应文章阅读的次数 #coding=utf-8 import re ret = re.findall(r"\d+", "python = 9999, c = 7890, c++ = 12345") print(ret) 运行结果:['9999', '7890', '12345']
8.2
sub(正则,替换的数据, 被替换的数据) 将匹配到的数据进行替换 返回值返回 被替换之后的数据结果 字符串 源字符串不变 参数2还可以是一个函数的名字 这个函数需要满足一下几个条件才可以被正则调用 必须要有一个参数 ----- 通过这个参数将正则的匹配对象传递进去 必须要有一个返回值 ----- 通过返回值 返回替换的数据 需求:将匹配到的阅读次数加1 方法1: #coding=utf-8 import re ret = re.sub(r"\d+", '998', "python = 997") print(ret) 运行结果:python = 998 方法2: #coding=utf-8 import re def add(temp): strNum = temp.group() num = int(strNum) + 1 return str(num) ret = re.sub(r"\d+", add, "python = 997") print(ret) 运行结果:python = 998
8.3
split(正则, 数据) split 根据匹配进行切割字符串,并返回一个列表 正则是描述切割的规则 返回值就是切割之后的列表 eg:切割字符串“info:xiaoZhang 33 shandong” #coding=utf-8 import re ret = re.split(r":| ","info:xiaoZhang 33 shandong") print(ret) 运行结果: ['info', 'xiaoZhang', '33', 'shandong']
9 贪婪模式与非贪婪模式
Python里数量词默认是贪婪的,总是尝试匹配尽可能多的字符; 在满足整体匹配的情况下 贪婪会尽可能的多匹配 非贪婪会尽可能少的匹配 如果想要让python使用非贪婪模式 在量词"*","?","+","{m,n}"等之后加上? 贪婪尽可能多,非贪婪尽可能少。 贪婪和非贪婪必须有一个前提就是满足整体匹配结果。 eg: >>> s="This is a number 234-235-22-423" >>> r=re.match(".+(\d+-\d+-\d+-\d+)",s) >>> r.group(1) '4-235-22-423' >>> r=re.match(".+?(\d+-\d+-\d+-\d+)",s) >>> r.group(1) '234-235-22-423' >>> re.match(r"aa(\d+)","aa2343ddd").group(1) '2343' >>> re.match(r"aa(\d+?)","aa2343ddd").group(1) '2' >>> re.match(r"aa(\d+)ddd","aa2343ddd").group(1) '2343' >>> re.match(r"aa(\d+?)ddd","aa2343ddd").group(1) '2343' In [36]: res = re.search("^(\w+)_(\w+?)$","hello_world") In [37]: res.group() Out[37]: 'hello_world' In [38]: res.group(1) Out[38]: 'hello' In [39]: res.group(2) Out[39]: 'world'
Python中字符串前面加上 r 表示原生字符串
自动会对字符串中的\进行转义 ---- > 解决在匹配多\的情况的困扰 >>> mm = "c:\\a\\b\\c" >>> mm 'c:\\a\\b\\c' >>> print(mm) c:\a\b\c >>> re.match("c:\\\\",mm).group() 'c:\\' >>> ret = re.match("c:\\\\",mm).group() >>> print(ret) c:\ >>> ret = re.match("c:\\\\a",mm).group() >>> print(ret) c:\a >>> ret = re.match(r"c:\\a",mm).group() >>> print(ret) c:\a >>> ret = re.match(r"c:\a",mm).group() Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'NoneType' object has no attribute 'group' >>> 与大多数编程语言相同,正则表达式里使用"\"作为转义字符,这就可能造成反斜杠困扰。 假如你需要匹配文本中的两个字符"\w",python语言层级会先尝试对\w进行转义 (比如\n\r\v\t\f\e\0等) 如果不属于ASCII码中的转义字符就会'\w'自动转义为两个反斜杠 \\w。 那么 使用编程语言的正则表达式里将需要4个反斜杠"\\": 对于python语言来讲会将两个连续的‘\’解释为一个\ 前两个和后两个分别用于在编程语言里转义成反斜杠,转换成两个反斜杠后再在正则表达式里转义成一个反斜杠。 Python里的原生字符串很好地解决了这个问题,有了原生字符串,再也不用担心是不是漏写了反斜杠,写出来的表达式也更直观。 >>> ret = re.match(r"c:\\a",mm).group() >>> print(ret) c:\a