参考资料: 1、菜鸟教程:https://www.runoob.com/regexp/regexp-tutorial.html 2、RegexOne:https://regexone.com/lesson/introduction_abcs (这个网站是刷题网站,如果不会用的话,百度翻译一下就知道了) 3、我学网安的好兄弟总结的PDF。
好,切入正题。
我想我们就直奔主题吧,不想废话了,能点进来的也是想学点干货嘛。
先把上面第二个刷题网址打开,然后上车。 顺便想打开第一个网址也行。
解题须知:
[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_]'。
下表从最高到最低说明了各种正则表达式运算符的优先级顺序:
首先,先调用模块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(pattern, text, flags=0)
参数释义:
pattern:正则规则
text:待处理文本
flags:修饰符
这个修饰符嘛,就上面那块儿大小写啊啥的。
匹配成功re.search方法返回一个匹配的对象,否则返回None。
我们可以使用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用于替换字符串中的匹配项。
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(pattern,string)
这是一种,我就不演示啦。
还有另一种,如果你想指定范围去全部搜索呢(一般也没吃那么饱去数) 这时候需要用到另一个函数:
compile 函数用于编译正则表达式,生成一个正则表达式( Pattern )对象。 re.compile(pattern[, flags])
有了这个之后呢,findall函数就可以这样用了:
findall(string[, pos[, endpos]])
pos : 可选参数,指定字符串的起始位置,默认为 0。 endpos : 可选参数,指定字符串的结束位置,默认为字符串的长度。
不信你看:
https://regexper.com/
就到这里吧。
我说的,我明天要会正则表达式! 今天就O了。。