同一位网友连续分享两套代码!Python正则单词统计实战讲解
之前第三套精简代码,就是这位网友分享的,现在他又分享了第四套正则写法,非常感谢这位网友热心分享!对比下来,处理这种带标点的英文歌词文本,第四种写法是这几版里面最好用的。今天我们一起来学习正则表达式,看看进阶版文本统计怎么做,我讲慢一点,新手朋友都能听懂。
第四套:网友分享正则进阶写法
import re
ts = "jingle bells,jingle bells,jingle \
all the way! oh what fun it is to \
ride in a one-horse open sleigh"
res = re.compile(r"[a-zA-Z']+").findall(ts)
t = {}
for i in res:t[i] = t.get(i,0) + 1
print(t)
逐条大白话详细讲解代码
1. import re
import 就是导入的意思。
re 是Python自带的正则工具包,正则用来快速筛选、清理文字。我们想要用正则功能,第一行必须写上这句话,把工具调出来。
2. ts = "jingle bells,jingle bells,jingle \ all the way! oh what fun it is to \ ride in a one-horse open sleigh"
ts 是我们自定义的变量,用来存放一段英文歌词。
每行末尾这个反斜杠,写在双引号外面,叫做续行符,作用是太长的字符串可以换到下一行书写,最后合并成完整的一长段文字。这个斜杠属于代码标记,不会保存到ts文本里面,不受后面正则r的影响。
大家看这段文字,里面有逗号、感叹号,还有空格,标点和单词混在一起,手动清理很麻烦,正好用正则自动清洗。
3. res = re.compile(r"[a-zA-Z']+").findall(ts)
这一整行是正则的核心,我们拆开慢慢说:
① re.compile() :就是把我们写好的筛选规则提前整理好,程序运行起来更快。
② r"[a-zA-Z']+"
先说最前面这个 r:
英文全称 raw,翻译过来就是原始的意思。
在Python里,如果字符串里面有反斜杠 \ ,程序默认会把它当成特殊指令,不会当成普通的斜杠文字,这个动作就叫转义。
举个例子: \n 本来是两个字符,不加r的时候,Python会理解成【换行】,直接实现换行效果,不再是普通的反斜杠+n。
如果加上 r, r"\n" 就原样保留,就是 \ 和 n 两个普通文字,不会执行换行。
这里要重点区分两种反斜杠:
第一种:引号内部的反斜杠,才受r控制,r会取消它的转义功能,原样读取;
第二种:引号外面、一行末尾的反斜杠,就是上面ts用到的续行符,它是给代码换行用的,不归r管理,不受r影响。
我们写正则规则的时候,经常会用到反斜杠,如果不加r,程序很容易乱解读符号,代码直接报错或者运行结果不对。
只要在双引号前面写上 r,就相当于告诉Python:引号里面所有文字,全部原样照读,不要自动做转义处理,里面写的是什么就是什么。
👉记住一个习惯:只要写正则匹配规则,引号前面统一加上 r,防止符号解析出错,这是行业通用写法。
引号内这一串就是筛选规则:
a-z 代表所有小写英文字母;
A-Z 代表所有大写英文字母;
' 代表英文缩写自带的单引号;
✅总结:这条规则会把小写字母、大写字母、缩写单引号,这三类字符全部提取出来。
加号 + 意思:连续符合上面规则的字符,合并成一整个单词。
👉什么时候会停止提取?
只要碰到不是小写字母、大写字母、单引号的字符(空格、逗号、感叹号、横杠等等),就立刻结束当前这个单词的读取,然后继续往后查找下一个单词。
比如 one-horse ,读到one后面的横杠,横杠不在匹配规则内,提取就停下,one单独作为一个单词,之后再继续读取horse。
👉举例子演示提取效果:
测试文字: "Don't stop! Hello,World let's go"
经过正则提取后结果: ["Don't", "stop", "Hello", "World", "let's", "go"]
逗号、感叹号直接过滤,Don't、let's 这类带单引号的缩写单词完整保留。
③ .findall(ts) :拿着上面的筛选规则,去ts这段歌词里面查找,把所有符合规则的单词全部找出来,放到列表res里面。
整行作用:自动丢掉逗号、感叹号这些多余标点,只提取英文单词。
⚠️补充:我们歌词里有 one-horse,中间的横杠不在匹配规则里,运行后会拆成 one 和 horse 两个单词,后面优缺点会讲到。
4. t = {}
大括号代表字典,我们定义空字典t,相当于一张空白统计表。
左边放单词,右边记录这个单词一共出现多少次。
5. for i in res:t[i] = t.get(i,0) + 1
简写一行循环,用来统计单词出现次数
6. print(t)
全部循环结束,所有单词统计完成,print 把整张统计表打印出来给我们看。
这套正则写法优缺点,大白话讲解
✅优点(也是为什么说这版更好):
1. 不用我们手动写好多行replace去替换各种各样的标点符号,文字杂乱的时候清洗更省事,一行正则就能筛选单词;
2. 可以保留 let's、don't 这种带单引号的英文缩写,不会把单词拆断;
3. 平时工作处理文章、歌词、日志文字,这种正则写法经常会用到,实用性最强。
⚠️缺点:
1. 属于进阶知识点,正则的符号规则比较多,零基础刚入门会觉得难懂,建议先把循环、字典基础学扎实再来学正则;
2. 筛选规则是固定写死的,像 one-horse 这种带横杠的单词,横杠不识别,单词会被拆开;
3. 正则里面符号很多,写错一个符号,程序结果就会出错,排查问题会更费劲。
总结
第三套是只用基础语法写的精简版本,适合新手弄懂底层原理;
第四套正则写法,处理混杂标点的文本更方便,综合实用性最强,是这几版里面最好用的方案。
这里再补充一句给新手朋友:以后大家碰到统计英文单词的需求,如果暂时还记不住这行正则
res = re.compile(r"[a-zA-Z']+").findall(ts)
不用死记硬背,可以直接抄下来套用。
学习编程,不用把所有代码全部背熟,现成成熟的代码片段直接复制使用,好处就是节省自己重复写代码的时间,拿来就能实现功能,提高我们写程序的效率,先用起来,用得多了慢慢自然就理解记住了。
学习顺序建议:先吃透基础循环和字典,再来学习正则,理解起来轻松很多!
代码运行结果
plaintext
{'jingle': 3, 'bells': 2, 'all': 1, 'the': 1, 'way': 1, 'oh': 1, 'what': 1, 'fun': 1, 'it': 1, 'is': 1, 'to': 1, 'ride': 1, 'in': 1, 'a': 1, 'one': 1, 'horse': 1, 'open': 1, 'sleigh': 1}