正则表达式学习
1. 什么是正则表达式
-
正则表达式(简称为regex)是由字符和特俗符合组成的字符串
-
能够按照某种模式匹配一系列有相似特征的字符串
[工具]
2. 正则表达式中的符号
符号 | 描述 | 示例 | 正则 | 测试案例 | 结果 |
---|---|---|---|---|---|
literal | 匹配文本字符串的字面值literal | foo | aab | aabbs | aab |
re1|re2 | 匹配正则表达式re1或者re2 | foo|name | aa | bsaabbs | aa bs |
. | 匹配任何字符(除了\n之外) | b.b^ | aab. | aabbs | aabb |
^ | 匹配字符串起始部分 | ^Name | |||
$ | 匹配字符串结束部分 | name$ | |||
* | 匹配0次或者多次前面出现的正则表达式 | [A-Za-z0-9]* | |||
+ | 匹配1次或者多次前面出现的正则表达式 | [a-z]+.\com | |||
? | 匹配0次或者1次前面出现的正则表达式 | name? | |||
{N} | 匹配N次前面出现的正则表达式 | [0-9]{3} | |||
{M,N} | 匹配M-N次前面出现的正则表达式 | [0-9]{5,9} | |||
[…] | 匹配来自字符集的任意单一字符 | [name] | |||
[…x-y…] | 匹配x-y范围中的任意单一字符 | [0-9],[A-Za-z] | |||
[^…] | 不匹配此字符集中出现的任何个一个字符,包括某一范围的字符(如果在此字符集中出现) | [name],[A-Za-z0-9] | |||
(*|+|?|{})? | 用于匹配上面频繁出现/重复出现符合的非贪婪版本(*、+、?、{}) | .*?[0-9] | |||
(…) | 匹配封闭式的正则表达式,然后另存为子组 | ([0-9]{3})?,f(oo|u)bar |
3. 正则表达式中的特殊字符
匹配特俗字符需要\转义
特殊字符 | 描述 | 示例 | 正则 | 测试案例 | 结果 |
---|---|---|---|---|---|
\d | 匹配任何十进制数字,与[0-9]一致(\D与\d相反,不匹配任何非数值型的数字) | data\d+.txt | \w{3} | gaghah3221 | 322 |
\w | 匹配任何字符数字字符,与[A-Za-z0-9_]相同(\W 与之相反) | [A-Za-z]\w+ | \w{3} | gaghah3221 | gag hah 322 |
\s | 匹配任何空格字符,与[\t\r\n\v\f]相同(\S与之相反) | of\sthe | h\s{3}3 | 1h 32 | h 3 |
\b | 匹配任何单词边界(\B与之相反) | \bThe\b | |||
\N | 匹配已保存的子组N | price:\16 | |||
\c | 逐字匹配任何特俗字符c(即,仅按照字面意义匹配,不匹配特俗含义) | ., \ , * | |||
\A(\Z) | 匹配字符串的起始(结束) | \ADear |
3.1 特殊字符使用\ 转义
例如: .\com
maicheng.com => .com
3.2 指定匹配选项
3.2.1. 使用[]指定要匹配的集合
[abc]{2} 指定匹配任意abc 两个字符的集合
字符 : aabbsabc
结果:aa bb ab
3.2.2 使用[^]指定不要匹配的内容
[^abc]{2} 指定不匹配abc 两个字符的集合
字符:aabbs1abc
结果 : s1
3.3 正则表达式分组
3.3.1 重复一个字符串时
3.3.2 使用() 进行分组,使用(?\w+)指定组名
- (\d{1,3}.){3}\d{1,3} 187.154.251.14 => 187.154.251.14
3.3.3 从左向右,以分组的左括号为标志,第一个出现的分组的组号为1,第二个为2,以此内推
-
使用 \1 \2 反向引用
字符
He love is small lover
He like is small liker正则
He (l…) is small \1r
He (?l…) is small \kr
3.3.4 表达式(A(B©))分组情况解析
0 | (A(B©)) |
---|---|
1 | (A) |
2 | (B©) |
3 | © |
3.4 贪婪模式和非贪婪模式
3.4.1 贪婪匹配
在整个表达式匹配成功的前提下,尽可能多的匹配
表达式 : ab.+c
测试数据 : abassscssscsss
结果 : abassscsssc
3.4.2 非贪婪匹配
在整个表达式匹配成功的前提下,匹配到就结束
只需要在匹配pattern中加上?
表达式 : ab.*?c
测试数据 : abassscssscsss
结果 : abasssc
3.5 练习
3.5.1 身份证匹配
案例 320723 1887 04 14 7487
-
前六位区域编号
-
接下来四位是出生年份
-
接下来四位月份日期
-
随后四位
-
倒数第二位 : 性别
表达式 : \d{17}([0-9]|X)
第二版 :(\d{6})(\d{4})((\d{2})(\d{2}))\d{2}\d{1}([0-9]|X)
https://tool.oschina.net/regex)
4. re 模块
属性 | 描述 |
---|---|
re.I re.INGORECASE | 不区分大小写的匹配 |
re.L re.LOCALE | 根据所使用的本地语言环境通过\w、\W、\b、\B、\s、\S实现匹配 |
re.M re.MULTILINE | ^和$分配匹配目标i字符串中行的起始和结尾,而不是严格匹配整个字符串本身的起始和和结尾 |
re.S re.DOTALL | “.”(点号)通常匹配除了\n (换行符)之外的所有单个字符;该标记表示“.”,(点号)能够匹配全部字符 |
re.X re.VERBOSE | 通过反斜线转义,否则所有空格加上# (以及在改行中所有后续文字)都被忽略,除非在一个字符类中或者允许注释并且一高可读性 |
4.1 compiler
- compiler(pattern, flags=0)
- 使用任何可选的标记来编译正则表达式的模式,然后返回一个正则表达式对象
- 推荐编译,但它不是必须的
4.2 match
-
match(pattern, string, flags=0)
-
尝试使用带有可选标记的正则表达式的模式来匹配字符串,如果成功,就返回匹配对象,如果匹配失败,就返回None
-
练习
import re pattern = re.compile(r'hello', re.I) result = pattern.match('Hello world') # 输出包含哪些正则 print(dir(pattern)) print(dir(result)) # 输出结果 print(result.string)
4.3 findall() 的使用
-
findall(pattern, string, [,flags])
-
查找字符串中使用所有(非重复)出现的正则表达式模式,并返回一个匹配列表
-
练习
import re content = 'one12two32three34four11' p = re.compile(r'[a-z]+', re.I) list = p.findall(content, ) print(list)
4.4 search的使用
- search(pattern, string, [,flags])
2.尝试使用带有可选标记的正则表达式的模式来匹配字符串,如果成功,就返回匹配对象,如果匹配失败,就返回None
-
练习
import re pattern = re.compile(r'world', re.I) result = pattern.search('Hello world') # 输出结果 print(result.string)
4.5 group()和groups() 使用
-
group(num) 返回整个匹配对象或编号为num的特定子组
-
groups(): 返回一个包含所有匹配子组的元祖(如果没有成功匹配,则返回一个空元祖)
-
练习
import re pattern = re.compile(r'world', re.I) result = pattern.search('Hello world') if result is not None: print(pattern.groups) def id_card(): content = '320723188704147487' pattern = re.compile(r'(\d{6})(?P<year>\d{4})((?P<month>\d{2})(\d{2}))\d{2}\d{1}([0-9]|X)') result = pattern.search(content) print(result.group()) print(result.group(1)) print(result.group(5)) print(result.groupdict(5)) if __name__ == '__main__': id_card()
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-u7lb7zPh-1668332297693)(C:\Users\maido\AppData\Roaming\Typora\typora-user-images\image-20221113171059739.png)]
4.6 spilt 分割
-
spilt (pattern, string, [,flags])
-
分割字符串中使用所有(非重复)出现的正则表达式模式,并返回一个匹配列表
-
练习
import re content = 'one12two32three34four11' p = re.compile(r'\d+', re.I) # 2 表示分割几位 list = p.split(content, 2) print(list)
4.7 替换
-
sub(spilt (pattern, string, flags=0)
-
替换字符串中使用所有(非重复)出现的正则表达式模式,并返回一个匹配列表
-
练习
import re content = 'one12two32three34four11' p = re.compile(r'\d+', re.I) list = p.sub('@', content) print(list) # 替换位置 s2 = 'hello world' p2 = re.compile(r'(\w+) (\w+)') result = p2.sub(r'\2 \1', s2) print(result) def f(m): """使用函数进行替换规则改变""" return m.group(2).upper() + ' ' + m.group(1) result_sub = p2.sub(lambda m: m.group(2).upper() + ' ' + m.group(1), s2 ) print(result_sub)
4.8 读取页面图片地址
- <img.+?src=“(.+?)”.+?>