好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

今天我把话放这儿,明天我要会【正则表达式】

参考资料: 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了。。

查看更多关于今天我把话放这儿,明天我要会【正则表达式】的详细内容...

  阅读:30次