参考资料: 1、菜鸟教程:https://HdhCmsTesthdhcms测试数据/regexp/regexp-tutorial.html 2、RegexOne:https://regexone测试数据/lesson/introduction_abcs (这个网站是刷题网站,如果不会用的话,百度翻译一下就知道了) 3、我学网安的好兄弟总结的PDF。
好,切入正题。
文章目录
第一题:普通字母匹配 第二题:大杂烩 第三题:否定式上场 第四题:依旧练否定式 第五题:捕获组 补缺补漏 贪婪与非贪婪匹配 定位符 修饰符 元字符串 运算符优先级 Python正则表达式 先给个模板函数吧 re.search方法 re.group(s)方法 re.sub方法 findall方法 re测试数据pile方法 正则表达式可视化工具我想我们就直奔主题吧,不想废话了,能点进来的也是想学点干货嘛。
先把上面第二个刷题网址打开,然后上车。 顺便想打开第一个网址也行。
第一题:普通字母匹配
解题须知:
[ABC]:匹配 [...] 中的所有字符 [A-Z]:[A-Z] 表示一个区间,匹配所有大写字母,[a-z] 表示所有小写字母。 ^:匹配输入字符串的开始位置,除非在方括号表达式中使用,当该符号在方括号表达式中使用时,表示不接受该方括号表达式中的字符集合。要匹配 ^ 字符本身,请使用 \^,下同。 $:匹配输入字符串的结尾位置。如果设置了 RegExp 对象的 Multiline 属性,则 $ 也匹配 '\n' 或 '\r'。 {}:标记限定符表达式 []:标记一个中括号表达式 {n}:n 是一个非负整数。匹配确定的 n 次 {n,}:n 是一个非负整数。至少匹配n 次 {n,m}:m 和 n 均为非负整数,其中n <= m。最少匹配 n 次且最多匹配 m 次
看概念终究是不好受的,还有可能看不懂。
来,看题目:
好,实现一下:
好啦(别跟我说什么[a-g]* 也能实现,咱是为了做题目而做题目吗?咱是为了尽可能多的把所有知识点串起来)。
第二题:大杂烩
来,看题目:
解题须再知:
正则匹配是从左到右顺序匹配的 *:匹配前面的子表达式零次或多次。 +:匹配前面的子表达式一次或多次。 [\s\S]:匹配所有。\s 是匹配所有空白符,包括换行,\S 非空白符,包括换行。 \w:匹配字母、数字、下划线。等价于 [A-Za-z0-9_] |:指明两项之间的一个选择。要匹配 |,请使用 \| ():标记一个子表达式的开始和结束位置。子表达式可以获取供以后使用
好,实现一下看:
有点长,截不下,就写这里吧:
^[a-z]{3,6}([ ]|[0-9]+)([ ]|[a-z]+|")([ = ]|123)*("|;)*$
第三题:否定式上场
解题还需知:
(?=pattern):正向肯定预查(look ahead positive assert),在任何匹配pattern的字符串开始处匹配查找字符串。例如,"Windows(?=95|98|NT|2000)"能匹配"Windows2000"中的"Windows",但不能匹配"Windows3.1"中的"Windows"。 (?!pattern):正向否定预查(negative assert),在任何不匹配pattern的字符串开始处匹配查找字符串。例如"Windows(?!95|98|NT|2000)"能匹配"Windows3.1"中的"Windows",但不能匹配"Windows2000"中的"Windows"。 (?<=pattern):反向(look behind)肯定预查,与正向肯定预查类似,只是方向相反。例如,"(?<=95|98|NT|2000)Windows"能匹配"2000Windows"中的"Windows",但不能匹配"3.1Windows"中的"Windows"。 (?<!pattern):反向否定预查,与正向否定预查类似,只是方向相反。例如"(?<!95|98|NT|2000)Windows"能匹配"3.1Windows"中的"Windows",但不能匹配"2000Windows"中的"Windows"。
我的题解:
第四题:依旧练否定式
解题须知:
[^ABC]:匹配除了 [...] 中字符的所有字符 \w:匹配字母、数字、下划线。等价于 [A-Za-z0-9_] .:匹配除换行符 \n 之外的任何单字符。要匹配 . ,请使用 \. 。
题解一:
题解二:
简单吧。 用某位大佬的话说,代码写出来,就是为了给人看的,只是顺便拿去给机器运行一下。
第五题:捕获组
说实话,我觉得这个题好像没必要。
这个你们别管了,我直接实现
题目呢,就讲解这些。 后面各位还需要加强训练,反正题库也给你们了。 做完一轮,可以选择addition再做一轮。
补缺补漏
来看看我们刚刚落下了哪些吧:
贪婪与非贪婪匹配
*和 + 限定符都是贪婪的,因为它们会尽可能多的匹配文字,只有在它们的后面加上一个 ? 就可以实现非贪婪或最小匹配。
定位符
\b:匹配一个单词边界,即字与空格间的位置 \B:非单词边界匹配
\b 字符的位置是非常重要的。如果它位于要匹配的字符串的开始,它在单词的开始处查找匹配项。如果它位于字符串的结尾,它在单词的结尾处查找匹配项。
下面的表达式匹配单词 Chapter 的开头三个字符,因为这三个字符出现在单词边界后面:
/\bCha/
下面的表达式匹配单词 Chapter 中的字符串 ter,因为它出现在单词边界的前面:
/ter\b/
修饰符
下表列出了正则表达式常用的修饰符:
存在即合理嘛。
使用方式如下:
元字符串
\d:匹配一个数字字符。等价于 [0-9]。 \D:匹配一个非数字字符。等价于 [^0-9]。 \w:匹配字母、数字、下划线。等价于'[A-Za-z0-9_]'。 \W:匹配非字母、数字、下划线。等价于 '[^A-Za-z0-9_]'。
运算符优先级
下表从最高到最低说明了各种正则表达式运算符的优先级顺序:
Python正则表达式
首先,先调用模块re。
先给个模板函数吧
def get_re(re_rule,text): t = re.search(re_rule, text) if t: #t = t.group(1) return t else: print("没有获取到有效内容") return t
应该能看得懂怎么用吧,我就不写注释啦。
现在让我们对着这个模板看:
re.search方法
re.search 扫描整个字符串并返回第一个成功的匹配。
re.search(pattern, text, flags=0)
参数释义:
pattern:正则规则 text:待处理文本 flags:修饰符
这个修饰符嘛,就上面那块儿大小写啊啥的。
匹配成功re.search方法返回一个匹配的对象,否则返回None。
re.group(s)方法
我们可以使用group(num) 或 groups() 匹配对象函数来获取匹配表达式。
group(num=0):匹配的整个表达式的字符串,group() 可以一次输入多个组号,在这种情况下它将返回一个包含那些组所对应值的元组。 groups():返回一个包含所有小组字符串的元组,从 1 到 所含的小组号。
import re line = "Cats are smarter than dogs" searchObj = re.search(r'(.*) are (.*?) .*', line, re.M | re.I) if searchObj: print("groups() : ", searchObj.groups()) print("group() : ", searchObj.group()) print("group(1) : ", searchObj.group(1)) print("group(2) : ", searchObj.group(2))
你悟到了吗?
re.sub方法
re.sub用于替换字符串中的匹配项。
sub(pattern, repl, string, count=0, flags=0)
repl: 替换的字符串,可以是函数 string: 要被查找替换的字符串 count: 模式匹配后替换的最大次数,默认0表示替换所有的匹配,可选
演示一下啊,替换掉某些不该出现的字符:
import re content = "do something fuck you" rs = re.sub(r'fuck', "*", content) print(rs)
这个太小儿科了啊,呐,前面说,这个repl可以是函数,是怎么肥四呢? 学过C语言的就知道这不就是函数指针嘛。
def calcWords(matched): num = len(matched.group()) return str(num * '*') content = "do something fuck you" rs = re.sub(r'fuck', calcWords, content) print(rs)
看这个函数,可能要有不少人犯嘀咕了,这个 calcWords 函数里面的参数 matched 是哪里来的?
据我大胆猜测啊,本来应该是这么写的:
def calcWords(partten,content): num = len(serch(partten,content).group()) return str(num * '*') content = "do something fuck you" rs = re.sub(r'fuck', calcWords, content) //pattern和content全部沦为calcWords的参数,这就是函数指针 print(rs)
不过Python嘛,一贯的简短,所以就写成了上面那样。
findall方法
在字符串中找到正则表达式所匹配的所有子串,并返回一个列表,如果没有找到匹配的,则返回空列表。
findall(pattern,string)
这是一种,我就不演示啦。
还有另一种,如果你想指定范围去全部搜索呢(一般也没吃那么饱去数) 这时候需要用到另一个函数:
re测试数据pile方法compile 函数用于编译正则表达式,生成一个正则表达式( Pattern )对象。 re测试数据pile(pattern[, flags])
有了这个之后呢,findall函数就可以这样用了:
findall(string[, pos[, endpos]])
pos : 可选参数,指定字符串的起始位置,默认为 0。 endpos : 可选参数,指定字符串的结束位置,默认为字符串的长度。
不信你看:
正则表达式可视化工具
https://regexper测试数据/
就到这里吧。
我说的,我明天要会正则表达式! 今天就O了。。
查看更多关于今天我把话放这儿,明天我要会【正则表达式】的详细内容...