关于正则表达式的学习笔记和总结
浅谈正则表达式
我有一个问题可以用正则表达式解决,好了现在我有两个问题了
为什么是正则表达式
在我个人的学习经历中接触过各种字符串查找函数,但为什么正则表达式这么神奇?我觉得是它的模糊性,它的模糊性决定了查找时无关元素的影响更小,更能找到需要的内容
用一段python代码举例
str = "abcdef"
res = str.find("a")
这个代码能帮助你找到字符串中a这个字符,但如果换个问题,在一堆电话号码中找某一个开头的电话,或者末尾是某一片段的电话号码,那么,find函数就没这么好用了。这时候,正则表达式的模糊性就能很好的得到需要的结果。
正则表达式的应用范围
正则表达式在java和python等语言中都有相应的包调用.在爬虫的使用中,正则表达式能很好的从一堆标签中找到你需要的某一段消息(虽然有时候在结构规整,目标不复杂的情况下,bs4有更好的效果).
正则表达式规则
元字符
.
:匹配除换行符之外的任意字符\w
:匹配字母或数字或下划线或汉字\W
:匹配不是字母或数字或下划线或汉字的字符\s
:匹配任意空白符\S
:匹配任意非空白符\d
:匹配数字\D
:匹配非数字\b
:匹配单词的开始或结束 如"er\b"
可以匹配never 不能匹配 very\A
:匹配字符串开头\z
:匹配字符串结尾,如果有换行符,则同时匹配换行符.\Z
:匹配字符串结尾,不匹配换行符.^
:匹配输入字符串的开始$
:匹配输入字符串的结束重复限定符
*
重复零次或者多次+
重复一次或多次?
重复零次或一次{n}
重复n次{n,}
重复n次或者多次{n,m}
重复n次或者m次分组符
(ab)
表明以字符串"ab"
为一组的元素,例如:"^(ab)+"
匹配以零个或者多个"ab"
开头的字符串[abc]
或者[a-c]
表明匹配abc中任意一个的字符转义符
\
表明将下一个字符标记为一个特殊字符、或一个原义字符、或一个向后引用、或一个八进制转义符。如:"(\n)"
表示匹配\n"(\(ab\))+"
表示匹配一个或者多个"(ab)"
的字符条件符
|
条件或,满足前者或者后者的字符,例如"(12)(3|4)"
匹配"123"
或者"124"
的字符断言
- 正向先行断言
表达式1(?=pattern)
匹配pattern前面的表达式,不包含本身,例如下面的代码import re line = "<div class = \"left_box\" height = 100px>" pattern = ".*(?=height)" m = re.search(pattern,line) print(m.group(0)) >>> <div class = "left_box"
- 负向先行断言
表达式1(?!pattern)
匹配后面不含pattern的表达式,不包含本身,例如下面的代码import re line = "regular regex rlief" pattern = r"r(\w{1})(?!g)" m = re.search(pattern,line) print(m.group(0)) >>> rl
- 正向后行断言
(?<=pattern)表达式1
,同正向先行断言,只是匹配的是pattern后面的表达式 - 负向向后行断言
(?<!pattern)表达式1
,同负向向先行断言,只是匹配的是pattern后面的表达式
懒惰(非贪婪)
什么是正则表达式的贪婪?
贪婪是指在匹配时尽可能多的匹配,如\w{2,9}
则会尽量匹配9个,如果不够就匹配八个.
如何做到懒惰
*?
重复0次或者无数次,从0开始匹配+?
重复一到正无穷次,从1开始??
重复0到1次,从0开始{n,m}?
重复n到m次,从n开始编号分组
- 数字编号分组
{表达式}
,例如:import re line = "020-85653333" pattern = r"(0\d{2,3})-(\d{8})" m = re.search(pattern,line) m.group(0) >>>020-85653333 m.group(1) >>>020 m.group(2) >>>85653333
- 命名编号捕获组
(?<name>表达式)
,非捕获组()?:表达式
,不捕获(在不同语言中实现方式不同,如在python中需要添加P在?与之间) import re line = "020-85653333" pattern = r"(?P<区号>0\d{2,3})-(?P<号码>\d{8})" m = re.search(pattern,line) m.group(0) >>>020-85653333 m.group("号码") >>>020 m.group("区号") >>>85653333 import re line = "020-85653333" pattern = r"(?P<区号>0\d{2,3})-(?:\d{8})" m = re.search(pattern,line) m.group(0) >>>020-85653333 m.group("号码") >>>Error m.group("区号") >>>85653333
python中re库介绍
修饰符
- re.I 大小写不敏感
- re.L 实现本地化识别(local-aware)匹配
- re.M 多行匹配
- re.S 匹配包括换行符在内的任何字符
- re.U 使用Unicode字符集解析字符
- re.X 该标志给予灵活格式.
方法
- search:从开头开始匹配,如果开头不匹配则失败
- findall:获取匹配的所有字符串
- sub:把匹配字符出从其中删去
- compile:将正则表达式编译成正则表达式对象,方便之后复用
- match:找到第一个匹配的字符串
参考网站
正则表达式在线匹配网站:https://c.runoob.com/front-end/854/