Python 正则表达式非贪婪表现得像贪婪
Python regex non-greedy acting like greedy
我正在处理成绩单,但在以非贪婪方式匹配模式时遇到了问题。它仍然抢得太多,看起来像是在进行贪婪的比赛。
成绩单如下所示:
>> John Doe:大家好,我是John Doe。
>> 大家好,我是李四。
>> 感谢您的光临,我们将在两分钟后开始。
>> Sam Smith:[无音频]大家早上好。
要在 >>(任意姓名): 中查找演讲者姓名,我写了
pattern=re.compile(r'>>(.*?):')
transcript='>> John doe: Hello, I am John Doe. >> Hello, I am Jane Doe. >> Thank you for coming, we will start in two minutes. >> Sam Smith: [no audio] Good morning, everyone.'
re.findall(pattern, transcript)
我期望 'John Doe'
和 'Sam Smith'
,但它给了我 'John Doe'
和 'Hello, I am Jane Doe. >> Thank you for coming, we will start in two minutes. >> Sam Smith'
我很困惑,因为.*?
是非贪婪的,(我认为)应该可以抢到'Sam Smith'
。我应该如何修复代码,以便它只抓取任何内容
>>(随便什么名字):?另外,我正在使用 Python 3.6.
谢谢!
你真的需要正则表达式吗?您可以拆分 >>
个提示,然后过滤掉您的名字。
>>> [i.split(':')[0].strip() for i in transcript.split('>>') if ':' in i]
['John doe', 'Sam Smith']
您对非贪婪正则表达式的理解略有偏差。非贪婪意味着它将匹配从开始匹配开始可能的最短匹配。如果在匹配中找到另一个字符,它不会更改开始匹配的字符。
例如:
start.*?stop
将匹配所有 startstartstop
,因为一旦它在 start
处开始匹配,它将一直匹配直到找到停止。非贪婪只是意味着对于字符串 startstartstopstop
,它只会匹配到第一站。
对于你的问题,这是一个使用正向前瞻很容易解决的问题。
您可以使用 >> ([a-zA-Z ]+)(?=:)
:
>>> transcript='>> John doe: Hello, I am John Doe. >> Hello, I am Jane Doe. >> Thank you for coming, we will start in two minutes. >> Sam Smith: [no audio] Good morning, everyone.'
>>> re.findall(r'>> ([a-zA-Z ]+)(?=:)', transcript)
['John doe', 'Sam Smith']
我正在处理成绩单,但在以非贪婪方式匹配模式时遇到了问题。它仍然抢得太多,看起来像是在进行贪婪的比赛。
成绩单如下所示:
>> John Doe:大家好,我是John Doe。
>> 大家好,我是李四。
>> 感谢您的光临,我们将在两分钟后开始。
>> Sam Smith:[无音频]大家早上好。
要在 >>(任意姓名): 中查找演讲者姓名,我写了
pattern=re.compile(r'>>(.*?):')
transcript='>> John doe: Hello, I am John Doe. >> Hello, I am Jane Doe. >> Thank you for coming, we will start in two minutes. >> Sam Smith: [no audio] Good morning, everyone.'
re.findall(pattern, transcript)
我期望 'John Doe'
和 'Sam Smith'
,但它给了我 'John Doe'
和 'Hello, I am Jane Doe. >> Thank you for coming, we will start in two minutes. >> Sam Smith'
我很困惑,因为.*?
是非贪婪的,(我认为)应该可以抢到'Sam Smith'
。我应该如何修复代码,以便它只抓取任何内容
>>(随便什么名字):?另外,我正在使用 Python 3.6.
谢谢!
你真的需要正则表达式吗?您可以拆分 >>
个提示,然后过滤掉您的名字。
>>> [i.split(':')[0].strip() for i in transcript.split('>>') if ':' in i]
['John doe', 'Sam Smith']
您对非贪婪正则表达式的理解略有偏差。非贪婪意味着它将匹配从开始匹配开始可能的最短匹配。如果在匹配中找到另一个字符,它不会更改开始匹配的字符。
例如:
start.*?stop
将匹配所有 startstartstop
,因为一旦它在 start
处开始匹配,它将一直匹配直到找到停止。非贪婪只是意味着对于字符串 startstartstopstop
,它只会匹配到第一站。
对于你的问题,这是一个使用正向前瞻很容易解决的问题。
您可以使用 >> ([a-zA-Z ]+)(?=:)
:
>>> transcript='>> John doe: Hello, I am John Doe. >> Hello, I am Jane Doe. >> Thank you for coming, we will start in two minutes. >> Sam Smith: [no audio] Good morning, everyone.'
>>> re.findall(r'>> ([a-zA-Z ]+)(?=:)', transcript)
['John doe', 'Sam Smith']