【问题标题】:Python regex non-greedy acting like greedyPython regex non-greedy 表现得像贪婪
【发布时间】:2018-10-12 02:23:47
【问题描述】:

我正在处理成绩单,但在以非贪婪方式匹配模式时遇到了麻烦。它仍然抢得太多了,看起来像是在做贪婪的比赛。

成绩单如下所示:

>> John Doe:你好,我是 John Doe。

>> 你好,我是 Jane Doe。

>> 谢谢你的光临,我们将在两分钟后开始。

>> Sam Smith:[无音频] 大家早上好。

为了在 >> (WHATEVER NAME): 中找到演讲者的姓名,我写了

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。

谢谢!

【问题讨论】:

  • 您误解了非贪婪的含义。这意味着从某个左锚点开始,它将尽可能少地读取以形成匹配。如果某个左锚点有任何匹配,它会保留它。它确实意味着它将把左边的锚拉到右边以缩短匹配。
  • 虽然与您想要的并不完全相同,但您可以简单地使用>> ([^>:])*:,除非您的名称中包含>
  • @BallpointBen 我明白了。谢谢你的澄清。这种情况我该怎么办?

标签: python regex python-3.x regex-greedy non-greedy


【解决方案1】:

您对非贪婪正则表达式的理解略有偏差。非贪婪意味着它将匹配从开始匹配时可能的最短匹配。如果在匹配中找到另一个字符,它不会更改开始匹配的字符。

例如:

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']

【讨论】:

    【解决方案2】:

    你真的需要正则表达式吗?您可以根据>> 提示进行拆分,然后过滤掉您的姓名。

    >>> [i.split(':')[0].strip() for i in transcript.split('>>') if ':' in i]
    ['John doe', 'Sam Smith']
    

    【讨论】:

    • 谢谢,成功了!对于这个特定的任务,我想我不需要正则表达式! :)
    • KISS(保持简单,Steffen)
    猜你喜欢
    • 2021-09-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多