关于正则表达式的学习笔记和总结
浅谈正则表达式
我有一个问题可以用正则表达式解决,好了现在我有两个问题了
为什么是正则表达式
在我个人的学习经历中接触过各种字符串查找函数,但为什么正则表达式这么神奇?我觉得是它的模糊性,它的模糊性决定了查找时无关元素的影响更小,更能找到需要的内容
用一段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("区号") >>>85653333python中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/