【问题标题】:Regular expressions: How do I find a sub-string that is between two regular expression matches?正则表达式:如何找到两个正则表达式匹配之间的子字符串?
【发布时间】:2014-03-19 20:42:58
【问题描述】:

假设我有一个字符串:

data = 'MESSAGE: Hello world!END OF MESSAGE'

我想得到'MESSAGE: ' 和下一个大写单词之间的字符串。消息中从来没有任何完全大写的单词。

我试图通过在re.search 中使用这个正则表达式来得到这个:

re.search('MESSAGE: (.*)([A-Z]{2,})', data).group(1)

在这里我希望它输出'Hello world!'- 但它总是返回错误的结果。在正则表达式中很容易找到出现在其他两个字符串之间的子字符串,但是如何在与正则表达式匹配的字符串之间找到子字符串。我曾尝试将其设为原始字符串,但这似乎不起作用。

我希望我能很好地表达自己——我在 Python 方面拥有丰富的经验,但对正则表达式不熟悉。如果可能的话,我想要一个解释以及如何使我的特定示例代码工作的示例。非常感谢任何有用的帖子。

顺便说一句,我使用的是 Python 3.3。

【问题讨论】:

  • 我不明白这一点:“你如何在与正则表达式匹配的字符串之间找到子字符串?”

标签: python regex string python-3.x


【解决方案1】:

您的代码不起作用,但原因相反:

re.search('MESSAGE: (.*)([A-Z]{2,})', data).group(1)

会匹配

'Hello world!END OF MESSA'

因为(.*) 是“贪婪的”,即它匹配最多允许其余(两个大写字符)匹配的字符。您需要使用非贪婪量词与

re.search('MESSAGE: (.*?)([A-Z]{2,})', data).group(1)

正确匹配

'Hello world!'

【讨论】:

  • 谢谢,这正是我需要的。
【解决方案2】:

一个小问号:

re.search('MESSAGE: (.*?)([A-Z]{2,})', data).group(1)
Out[91]: 'Hello world!'

如果你让第一个捕获组变得懒惰,它不会消耗感叹号之后的任何东西。

【讨论】:

    【解决方案3】:

    你需要你的 .* 是非贪婪的(见第一个?),这意味着它在下一个项目可以匹配的点停止匹配,你需要第二组是非捕获的(见?:)。

    import re 
    data = 'MESSAGE: Hello world!END OF MESSAGE'    
    regex = r'MESSAGE: (.*?)(?:[A-Z]{2,})'
    re.search(regex, data).group(1)
    

    返回:

    'Hello world!'
    

    或者,你可以使用这个:

    regex = r'MESSAGE: (.*?)[A-Z]{2,}'
    

    为了打破这一点(我将在搜索行中加入 VERBOSE 标志:):

    regex = r'''
             MESSAGE:\s    # first part, \s for the space (matches whitespace)
             (.*?)         # non-greedy, anything but a newline
             (?:[A-Z]{2,}) # a secondary group, but non-capturing,
                           #  good for alternatives separated by a pipe, |
             '''
    re.search(regex, data, re.VERBOSE).group(1)
    

    【讨论】:

    • 你为什么让第二组不捕获?
    • 他想返回第一组而不是第二组。
    • 那么.. 根本不让它成为一个组?就我个人而言,我认为他有这个组织的原因,所以我把它留在了。
    猜你喜欢
    • 1970-01-01
    • 2012-09-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-19
    • 1970-01-01
    • 2018-07-16
    相关资源
    最近更新 更多