正则表达式:search、finditer、findall三个方法的介绍

import re
text = "当下赵吹鸾首先答道:“那时奴辈的思想,尚未知陛下是何等样人,若是照直说了出来,恐撄圣怒,其罪非轻。”沛公道:“我不见罪你们,放心大胆地说出就是。”赵吹鸾听了,方才微笑奏道:“奴当城破之时,尚卧在床,心里默念,亡帝荒淫无道,又有那个姓赵的奸臣,只知助纣为虐,逢君之恶,对于天下诸侯,自然十分苛待,因此惹起干戈。一旦亡国,那班杀人不眨眼的将士,走入宫来,奴等必死乱刀之下。如此惨苦,岂不可怕!当时心理,未免怪着亡帝,早能行些仁政,便可长保江山。那时我们也好长在宫中伴驾,朝朝寒食,夜夜元宵,方不辜负天生丽质,得享富贵荣华。那料陛下如此仁厚,如此多情。在此刻是只望陛下大事定后,奴等得以长侍宫帏,便无他望的了。”"
pattern = r':“(.+?)”'
matches = re.findall(pattern, text)
for match in matches:
    print(match)

我的目的是什么?

我的目的是将小说中人物说的话都提取出来。

我写的正则表达式是:“(.+?)”

我得到的结果如下:

那时奴辈的思想,尚未知陛下是何等样人,若是照直说了出来,恐撄圣怒,其罪非轻。
我不见罪你们,放心大胆地说出就是。
奴当城破之时,尚卧在床,心里默念,亡帝荒淫无道,又有那个姓赵的奸臣,只知助纣为虐,逢君之恶,对于天下诸侯,自然十分苛待,因此惹起干戈。一旦亡国,那班杀人不眨眼的将士,走入宫来,奴等必死乱刀之下。如此惨苦,岂不可怕!当时心理,未免怪着亡帝,早能行些仁政,便可长保江山。那时我们也好长在宫中伴驾,朝朝寒食,夜夜元宵,方不辜负天生丽质,得享富贵荣华。那料陛下如此仁厚,如此多情。在此刻是只望陛下大事定后,奴等得以长侍宫帏,便无他望的了。

解释

这个正则表达式 :“(.+?)” 旨在匹配一个特定格式的字符串,具体解释如下:

  • :匹配中文冒号字符。

这里需要注意的是,在正则表达式中,冒号 : 本身并不是一个特殊字符,所以不需要转义。

但由于它前面有一个中文字符“:”,因此这个部分会匹配这个中文字符和紧跟其后的英文冒号。

  • :匹配中文左引号字符。同样,这个字符在正则表达式中也不是特殊字符,所以直接使用即可。

  • (.+?):这是一个捕获组,用于匹配并捕获一系列字符。

  • .:匹配除了换行符之外的任何单个字符

  • +:表示前面的元素(.)可以出现一次或多次。

  • ?:放在 + 后面,使 + 的行为变得非贪婪,即尽可能少地匹配字符

  • :匹配中文右引号字符。

整体来看,这个正则表达式会

匹配以中文冒号和中文左引号开始

后面跟着任意数量的字符(但尽可能少地匹配)

最后以中文右引号结束的字符串

捕获组会捕获这个字符串中的字符部分。

我的需求变更了 - re.search(pattern, text)

我现在想要打印出来的,不仅仅是双引号里头的,也就是不仅仅是捕获组里头的内容。

我希望打印出来的是整体匹配的内容。

也就是整个匹配字符串,不仅仅是捕获组中的内容

也可以修改代码变成下面的样子:

import re
text = "当下赵吹鸾首先答道:“那时奴辈的思想,尚未知陛下是何等样人,若是照直说了出来,恐撄圣怒,其罪非轻。”沛公道:“我不见罪你们,放心大胆地说出就是。”赵吹鸾听了,方才微笑奏道:“奴当城破之时,尚卧在床,心里默念,亡帝荒淫无道,又有那个姓赵的奸臣,只知助纣为虐,逢君之恶,对于天下诸侯,自然十分苛待,因此惹起干戈。一旦亡国,那班杀人不眨眼的将士,走入宫来,奴等必死乱刀之下。如此惨苦,岂不可怕!当时心理,未免怪着亡帝,早能行些仁政,便可长保江山。那时我们也好长在宫中伴驾,朝朝寒食,夜夜元宵,方不辜负天生丽质,得享富贵荣华。那料陛下如此仁厚,如此多情。在此刻是只望陛下大事定后,奴等得以长侍宫帏,便无他望的了。”"
pattern = r':“(.+?)”'
match = re.search(pattern, text)
if match:
    print(match.group(0)) # 这是整个匹配的字符串
    print(match.group(1)) # 这是捕获组中的字符串

上面的代码输出的结果是什么?

:“那时奴辈的思想,尚未知陛下是何等样人,若是照直说了出来,恐撄圣怒,其罪非轻。”
那时奴辈的思想,尚未知陛下是何等样人,若是照直说了出来,恐撄圣怒,其罪非轻。

这个满足了要求吗?这个TMD没有满足要求。

re.search(pattern, text)用于在字符串text中搜索与正则表达式 pattern 匹配的第一个位置。

如果找到匹配项,它会返回一个匹配对象;如果没有找到,它会返回 None。

这个对象身上match.group(0)是完整的匹配字符串

这个对象身上match.group(1)是捕获组的内容

我的需求没有得到满足

进一步尝试满足我的需求 - re.finditer(pattern, text)

import re
text = "当下赵吹鸾首先答道:“那时奴辈的思想,尚未知陛下是何等样人,若是照直说了出来,恐撄圣怒,其罪非轻。”沛公道:“我不见罪你们,放心大胆地说出就是。”赵吹鸾听了,方才微笑奏道:“奴当城破之时,尚卧在床,心里默念,亡帝荒淫无道,又有那个姓赵的奸臣,只知助纣为虐,逢君之恶,对于天下诸侯,自然十分苛待,因此惹起干戈。一旦亡国,那班杀人不眨眼的将士,走入宫来,奴等必死乱刀之下。如此惨苦,岂不可怕!当时心理,未免怪着亡帝,早能行些仁政,便可长保江山。那时我们也好长在宫中伴驾,朝朝寒食,夜夜元宵,方不辜负天生丽质,得享富贵荣华。那料陛下如此仁厚,如此多情。在此刻是只望陛下大事定后,奴等得以长侍宫帏,便无他望的了。”"
pattern = r':“(.+?)”'
matches = re.finditer(pattern, text)
for match in matches:
    print(match.group(0)) # 输出每个匹配的完整字符串
for match in matches:
    print(match.group(1)) # 输出每个匹配的捕获组内容

上面的代码得到的结果如下:

:“那时奴辈的思想,尚未知陛下是何等样人,若是照直说了出来,恐撄圣怒,其罪非轻。”
:“我不见罪你们,放心大胆地说出就是。”
:“奴当城破之时,尚卧在床,心里默念,亡帝荒淫无道,又有那个姓赵的奸臣,只知助纣为虐,逢君之恶,对于天下诸侯,自然十分苛待,因此惹起干戈。一旦亡国,那班杀人不眨眼的将士,走入宫来,奴等必死乱刀之下。如此惨苦,岂不可怕!当时心理,未免怪着亡帝,早能行些仁政,便可长保江山。那时我们也好长在宫中伴驾,朝朝寒食,夜夜元宵,方不辜负天生丽质,得享富贵荣华。那料陛下如此仁厚,如此多情。在此刻是只望陛下大事定后,奴等得以长侍宫帏,便无他望的了。”

只有整个匹配字符串的内容,没有打印出来捕获组中的内容。

这是为什么呢?

这是为什么呢?

这是因为re.finditer(pattern, text)返回的是一个迭代器

迭代器在遍历一次之后就会消耗掉所有的元素,这意味着你不能够再次遍历同一个迭代器来获取相同的结果

如果你要多次遍历匹配的结果,那么要怎么办呢?

上面的代码,我当然可以在打印了match.group(0)之后接着打印match.group(1)。

但是我不想要这么干,对,我就是这么倔强。

我们可以将迭代器转换成为列表,这样不就行了?

import re
text = "当下赵吹鸾首先答道:“那时奴辈的思想,尚未知陛下是何等样人,若是照直说了出来,恐撄圣怒,其罪非轻。”沛公道:“我不见罪你们,放心大胆地说出就是。”赵吹鸾听了,方才微笑奏道:“奴当城破之时,尚卧在床,心里默念,亡帝荒淫无道,又有那个姓赵的奸臣,只知助纣为虐,逢君之恶,对于天下诸侯,自然十分苛待,因此惹起干戈。一旦亡国,那班杀人不眨眼的将士,走入宫来,奴等必死乱刀之下。如此惨苦,岂不可怕!当时心理,未免怪着亡帝,早能行些仁政,便可长保江山。那时我们也好长在宫中伴驾,朝朝寒食,夜夜元宵,方不辜负天生丽质,得享富贵荣华。那料陛下如此仁厚,如此多情。在此刻是只望陛下大事定后,奴等得以长侍宫帏,便无他望的了。”"
pattern = r':“(.+?)”'
matches_iter = re.finditer(pattern, text)
matches_list = list(matches_iter)
for match in matches_list:
    print(match.group(0)) # 输出每个匹配的完整字符串
for match in matches_list:
    print(match.group(1)) # 输出每个匹配的捕获组内容

得到的结果是什么呢?

:“那时奴辈的思想,尚未知陛下是何等样人,若是照直说了出来,恐撄圣怒,其罪非轻。”
:“我不见罪你们,放心大胆地说出就是。”
:“奴当城破之时,尚卧在床,心里默念,亡帝荒淫无道,又有那个姓赵的奸臣,只知助纣为虐,逢君之恶,对于天下诸侯,自然十分苛待,因此惹起干戈。一旦亡国,那班杀人不眨眼的将士,走入宫来,奴等必死乱刀之下。如此惨苦,岂不可怕!当时心理,未免怪着亡帝,早能行些仁政,便可长保江山。那时我们也好长在宫中伴驾,朝朝寒食,夜夜元宵,方不辜负天生丽质,得享富贵荣华。那料陛下如此仁厚,如此多情。在此刻是只望陛下大事定后,奴等得以长侍宫帏,便无他望的了。”
那时奴辈的思想,尚未知陛下是何等样人,若是照直说了出来,恐撄圣怒,其罪非轻。
我不见罪你们,放心大胆地说出就是。
奴当城破之时,尚卧在床,心里默念,亡帝荒淫无道,又有那个姓赵的奸臣,只知助纣为虐,逢君之恶,对于天下诸侯,自然十分苛待,因此惹起干戈。一旦亡国,那班杀人不眨眼的将士,走入宫来,奴等必死乱刀之下。如此惨苦,岂不可怕!当时心理,未免怪着亡帝,早能行些仁政,便可长保江山。那时我们也好长在宫中伴驾,朝朝寒食,夜夜元宵,方不辜负天生丽质,得享富贵荣华。那料陛下如此仁厚,如此多情。在此刻是只望陛下大事定后,奴等得以长侍宫帏,便无他望的了。

把迭代器转换成为了列表,你TMD想要迭代多少次,就迭代多少次。

最终还是我自己解决了

我修改了我的正则表达式,利用了re.findall(pattern, text)返回捕获组中内容的特点,根据这个特点修改了我的正则表达式。

也算是拿到了我想要的输出结果。

import re
text = "当下赵吹鸾首先答道:“那时奴辈的思想,尚未知陛下是何等样人,若是照直说了出来,恐撄圣怒,其罪非轻。”沛公道:“我不见罪你们,放心大胆地说出就是。”赵吹鸾听了,方才微笑奏道:“奴当城破之时,尚卧在床,心里默念,亡帝荒淫无道,又有那个姓赵的奸臣,只知助纣为虐,逢君之恶,对于天下诸侯,自然十分苛待,因此惹起干戈。一旦亡国,那班杀人不眨眼的将士,走入宫来,奴等必死乱刀之下。如此惨苦,岂不可怕!当时心理,未免怪着亡帝,早能行些仁政,便可长保江山。那时我们也好长在宫中伴驾,朝朝寒食,夜夜元宵,方不辜负天生丽质,得享富贵荣华。那料陛下如此仁厚,如此多情。在此刻是只望陛下大事定后,奴等得以长侍宫帏,便无他望的了。”"
pattern = r'(:“(.+?)”)'
matches_tuple = re.findall(pattern, text)
for match in matches_tuple:
    print(match[0]) 
    print(match[1]) 

上面的输出结果是什么呢?

:“那时奴辈的思想,尚未知陛下是何等样人,若是照直说了出来,恐撄圣怒,其罪非轻。”
那时奴辈的思想,尚未知陛下是何等样人,若是照直说了出来,恐撄圣怒,其罪非轻。
:“我不见罪你们,放心大胆地说出就是。”
我不见罪你们,放心大胆地说出就是。
:“奴当城破之时,尚卧在床,心里默念,亡帝荒淫无道,又有那个姓赵的奸臣,只知助纣为虐,逢君之恶,对于天下诸侯,自然十分苛待,因此惹起干戈。一旦亡国,那班杀人不眨眼的将士,走入宫来,奴等必死乱刀之下。如此惨苦,岂不可怕!当时心理,未免怪着亡帝,早能行些仁政,便可长保江山。那时我们也好长在宫中伴驾,朝朝寒食,夜夜元宵,方不辜负天生丽质,得享富贵荣华。那料陛下如此仁厚,如此多情。在此刻是只望陛下大事定后,奴等得以长侍宫帏,便无他望的了。”
奴当城破之时,尚卧在床,心里默念,亡帝荒淫无道,又有那个姓赵的奸臣,只知助纣为虐,逢君之恶,对于天下诸侯,自然十分苛待,因此惹起干戈。一旦亡国,那班杀人不眨眼的将士,走入宫来,奴等必死乱刀之下。如此惨苦,岂不可怕!当时心理,未免怪着亡帝,早能行些仁政,便可长保江山。那时我们也好长在宫中伴驾,朝朝寒食,夜夜元宵,方不辜负天生丽质,得享富贵荣华。那料陛下如此仁厚,如此多情。在此刻是只望陛下大事定后,奴等得以长侍宫帏,便无他望的了。

相当完美的输出结果。

我干这个事,有什么用处呢?

并没有什么屁用

结论

通过这个突发奇想的小膈应小需求。

我熟悉了三个函数的用法。

第一个是re.search(pattern, text)

这个玩意只会去搜text中匹配的第一个对象。

然后返回的倒是一个可迭代对象。

可以取出来整个匹配字符串,也可以取出来捕获组中的内容。

(我的正则表达式当中都是使用捕获组的。)

但是我还是要说,这个函数最TMD没本事,看都不要看到它。

第二个是re.finditer(pattern, text)

这个破玩意倒是能够把全部的东西匹配出来。

它返回的是一个迭代器。

但是一定要注意迭代器只能够遍历一次。

需要把迭代器变成列表,

那么遍历这个列表,就可以拿到匹配字符串和捕获组了。

也算是满足了需求。

第三个是re.findall(pattern, text)

这个破玩意最不是东西。

你的pattern当中如果是写了捕获组,它就只给你返回捕获组当中的内容。

然后匹配到全部的,放到一个tuple当中。

你可以遍历你的tuple。

我是通过捕获组嵌套变相达成了需求的。


我在我的正则表达式当中使用了捕获组,

我使用re.findall(pattern, text)来进行匹配,

我会获得一个元组,

这个元组中的内容将会是匹配到的捕获组中的内容,

不是整个匹配到到匹配字符串的内容,

我说的有没有问题?

一点问题都没有的嘛。

  • 9
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值