读到一段巧妙的正则表达式,勾起我对正则表达式欠缺知识点的探寻: P y t h o n Python Python正则表达式中的“回引用(回溯)”——分组别名引用与序号引用的差异及正则表达式中的“P”关键字详情。
(笔记模板由python脚本于2024年01月14日 07:49:35创建,本篇笔记适合熟悉基础编程,了解正则表达式的coder翻阅)
Python 官网:https://www.python.org/
Free:大咖免费“圣经”教程《 python 完全自学教程》,不仅仅是基础那么简单……
地址:https://lqpybook.readthedocs.io/
??自学并不是什么神秘的东西,一个人一辈子自学的时间总是比在学校学习的时间长,没有老师的时候总是比有老师的时候多。
????????????—— 华罗庚
本文质量分:
CSDN质量分查询入口:http://www.csdn.net/qc
奇妙
p
y
t
h
o
n
python
python代码
text = '''I have two feet, it has one foot.
She's singing a song.
canada bananas'''
result = re.findall(r'(\b\w*(?P<f>\w+)(?P=f)\w*\b)', text)
print(result)
??上面这段代码,是在闲逛 c s d n csdn csdn时捡回来的,当时是因为新奇它的正则表达写法,因为没见过,也读不明白,就 c v cv cv回来了。更“惊艳”其输出: [ ( ′ f e e t ′ , ′ e ′ ) , ( ′ f o o t ′ , ′ o ′ ) , ( ′ s i n g i n g ′ , ′ i n g ′ ) , ( ′ b a n a n a s ′ , ′ n a ′ ) ] [('feet', 'e'), ('foot', 'o'), ('singing', 'ing'), ('bananas', 'na')] [(′feet′,′e′),(′foot′,′o′),(′singing′,′ing′),(′bananas′,′na′)]
上面那个代码运行截屏图片
r'(\b\w*(?P<f>\w+)(?P=f)\w*\b)'
,为啥可以有这样子的输出,我“百思不得其解”,也没有搜索到恰当的答案,就一直搁置了下来。??今天我才幡然醒悟,“为何不让我的ai助理智谱清言给解析解析”。世上流行的AI,大多对书写代码非常在行,尤其对Python更是精通。
神奇
”代码向我的
a
i
ai
ai助理智谱清言提问截屏图片
智
谱
清
言
智谱清言
智谱清言回复文本
原文抄录:
?
??在您提供的文本中,使用正则表达式 \w*(?P<f>\w+)(?P=f)\w*
尝试匹配的是一个特定的模式,该模式试图找到一个单词,然后它自己重复一次,并被一个或多个字母包围。但这个表达式可能会产生一些问题,因为它试图匹配的重复单词部分可能会匹配到字符串中重复出现的单词,而不是特定模式下的重复。
例如,在 “I have two feet, it has one foot.
” 这句话中,“two
” 和 “one
” 都是完整的单词,所以它们会匹配这个表达式。但在 “foot” 中,“oo” 部分并不符合该模式,因为它不是由一个单词重复而来。
?
??正则表达式 r'\w+'
将会匹配一个或多个字母或数字字符组成的单词。所以,如果要用这个表达式来找到所有单词,可以这样写:
import re
text = '''I have two feet, it has one foot.
She's singing a song.
Canada bananas'''
result = re.findall(r'\w+', text)
print(f"\n文本:\n{text}\n\nre通配表达式:r'\w+'\nre.findall函数匹配结果:\n{result}\n\n{'':~^40}")
??这段代码会找到并打印出文本中所有的单词。
??在您的代码中,注释掉的
f
i
n
d
a
l
l
findall
findall 函数调用使用了不同的正则表达式,但由于该表达式的问题,它可能不会按预期工作。在正则表达式中,(?P=f)
是一种回引用,它指的是在同一个正则表达式中定义的命名捕获组 。但在这个特定的表达式中,它的使用可能是不正确的,因为它试图匹配的是同一个捕获组的内容,这在没有其他组提供内容的情况下是无法工作的。
??如果您的目标是找到所有重复的单词,您可能需要调整正则表达式以适应您的具体需求,或者使用其他方法来处理文本。如果您有更具体的模式或者需求,请提供详细信息,以便我能够给出更准确的帮助。
??从回复文本可以看出,“智谱清言”对中文语义的“理解”也是比较到位的,虽然有些绕,但已经不妨碍我理解了。😜
从
a
i
ai
ai回复中,我终于明白了,“神奇
”代码用了一种叫
回
引
用
回引用
回引用的正则表达式“魔法糖
”,产生了我认为的“近乎奇幻
”的输出。
回引用
”??再问问“
智
谱
清
言
智谱清言
智谱清言”回引用
是个啥吧。
向我的
a
i
ai
ai助理智谱清言提问截屏图片
回复文本
原文抄录:named capture group
)或非命名捕获组(unnamed capture group
)的内容。回引用的目的是为了匹配之前匹配到的文本。\num
或\name
形式来表示回引用,其中num
是捕获组的编号,而name
是捕获组的名称。\1
就是对第一个捕获组(即 <word>
)的回引用,它将会匹配与 <word>
中相同的内容。这意味着整个表达式将会匹配一个单词后跟一个与这个单词相同的单词,例如 “apple apple
”。??这个“概念解释”的回复完全是$ai$吐人言,我毫不费力地阅读和理解了。😜
??正则通配表达式中的“P
”,是被我遗漏的知识点
。它一直都在,只是被我无情遗漏在了角落。
“P”的知识点
给分组取别名
f
f
f的Python代码
text = '''I have two feet, it has one foot.
She's singing a song.
canada bananas'''
result = re.findall(r'(\b\w*(?P<f>\w+)(?P=f)\w*\b)', text)
print(result)
给分组取别名
n
a
m
e
name
name的Python代码
text = '''I have two feet, it has one foot.
She's singing a song.
canada bananas'''
result = re.findall(r'(\b\w*(?P<name>\w+)(?P=name)\w*\b)', text)
print(result)
代码运行效果截屏图片
非数字字符
(如果是数字字符,可能会被误认为是序号引用),甚至可以是中文。中文分组
n
a
m
e
name
name
result = re.findall(r'(\b\w*(?P<梦>\w+)(?P=梦)\w*\b)', text)
print(result)
n
a
m
e
name
name是下划线
result = re.findall(r'(\b\w*(?P<_>\w+)(?P=_)\w*\b)', text)
print(result)
p
y
t
h
o
n
python
python代码
regexStr = r'(\b\w*(?P<name>\w+)(?P=name)+(?P=name)*\w*\b)'
regex = compile(regexStr)
regexStr2 = r'(\b\w*(?P<name>\w+)(\2)(\2)*\w*\b)'
regex2 = compile(regexStr2)
regexStr3 = r'(\b\w*(?P<name>\w+)(?P=name)+(?P=name)*(?P=name)*\w*\b)'
regex3 = compile(regexStr3)
print(f"\n文本:\n{text}\n\nre通配表达式:\n1、“{regexStr}”,\n有{regex.groups}个分组{regex.findall(text)[0]};\n\n2、“{regexStr3}”,有{regex3.groups}个分组分组{regex3.findall(text)[0]};\n\n3、“{regexStr2}”,有{regex2.groups}个分组分组{regex2.findall(text)[0]}。\n")
代码运行效果截屏图片
??由代码及运行效果截屏图片可以看出,别名引用,不管用别名引用多少次,都只增加一个分组;而序号引用,一次引用算一个分组。再如:
Python代码
text = '''I have two feet, it has one foot.
She's singinginginging a song.
canada bananas'''
regexStr = r'(\b\w*(?P<name>\w+)(?P=name)+(?P=name)+\w*(?P=name)+(?P=name)+\b)'
regex = compile(regexStr)
result = regex.findall(text)
if result:
print(f"\n文本:\n{text}\n\nre通配表达式:\n“{regexStr}”,\n有{regex.groups}个分组{result}")
else:
print(f"\n文本:\n{text}\n\nre通配表达式:\n“{regexStr}”,\n有{regex.groups}个分组,无法在文本中匹配。")
运行效果截屏图
Python代码
regexStr = r'(\b\w*(?P<name>\w+)(\2)+(\2)+\w*(\2)+(\2)+\b)'
运行效果截屏图
python代码
regexStr = r'(\b\w*(\w+)(\2)+(\2)+\w*(\2)+(\2)+\b)'
代码运行效果截屏
??不管分组取没取别名,只要是用序号回引用,都是一样引用一次会增加一个分组。
a
a
a、关于正则“反向引用
(回溯)”的精彩分析文章
b b b、python——正则表达式(re模块)详解
(源码较长,点此跳过源码)
#!/sur/bin/nve python
# coding: utf-8
import re
from re import compile
text = '''I have two feet, it has one foot.
She's singinginginging a song.
canada bananas'''
#regexStr = r'(\b\w*(?P<name>\w+)(?P=name)+(?P=name)+\w*(?P=name)+(?P=name)+\b)'
#regexStr = r'(\b\w*(?P<name>\w+)(\2)+(\2)+\w*(\2)+(\2)+\b)'
regexStr = r'(\b\w*(\w+)(\2)+(\2)+\w*(\2)+(\2)+\b)'
regex = compile(regexStr)
result = regex.findall(text)
if result:
print(f"\n文本:\n{text}\n\nre通配表达式:\n“{regexStr}”,\n有{regex.groups}个分组{result}")
else:
print(f"\n文本:\n{text}\n\nre通配表达式:\n“{regexStr}”,\n有{regex.groups}个分组,无法在文本中匹配。")
exit()
text = '''I have two feet, it has one foot.
She's singing a song.
canada bananas'''
result = re.findall(r'(\b\w*(?P<f>\w+)(?P=f)\w*\b)', text)
print(result)
result = re.findall(r'(\b\w*(?P<梦>\w+)(?P=梦)\w*\b)', text)
print(result)
result = re.findall(r'(\b\w*(?P<_>\w+)(?P=_)\w*\b)', text)
print(result)
regexStr = r'(\b\w*(?P<name>\w+)(?P=name)+(?P=name)*\w*\b)'
regex = compile(regexStr)
regexStr2 = r'(\b\w*(?P<name>\w+)(\2)(\2)*\w*\b)'
regex2 = compile(regexStr2)
regexStr3 = r'(\b\w*(?P<name>\w+)(?P=name)+(?P=name)*(?P=name)*\w*\b)'
regex3 = compile(regexStr3)
print(f"\n文本:\n{text}\n\nre通配表达式:\n1、“{regexStr}”,\n有{regex.groups}个分组{regex.findall(text)[0]};\n\n2、“{regexStr3}”,有{regex3.groups}个分组分组{regex3.findall(text)[0]};\n\n3、“{regexStr2}”,有{regex2.groups}个分组分组{regex2.findall(text)[0]}。\n")
exit()
regex = compile(regexStr)
regex2 = compile(regexStr2)
result = regex.findall(text)
print(f"\n文本:\n{text}\n\nre通配表达式:\n1、“{regexStr}”,\n有{regex.groups}个分组。\n\n2、“{regexStr2}”,有{regex2.groups}个分组。\n\n输出:\nre.findall函数匹配前面文本结果:\n{result}\n\n{'':~^40}")
我的HOT博:
??本次共计收集289篇博文笔记信息,总阅读量44.72w。数据采集于2023年12月11日 23:07:13,用时5分11.8秒。阅读量不小于4.0k的有17篇。
截屏图片
精品文章:
来源:老齐教室
◆ Python 入门指南【Python 3.6.3】
好文力荐:
CSDN实用技巧博文: