【问题标题】:How to match from a word up to the end of a sentence?如何从单词匹配到句尾?
【发布时间】:2019-04-29 04:27:11
【问题描述】:

我想用 python regex python 把“is”这个词后面的整个句子。

我的代码:

s = '''Robert is an English actor, model and musician.
He started his film career by playing Cedric Diggory in Harry Potter.'''
r = re.findall(r'(?:is) (.*)',s)
print(r)

我希望输出是:

'an English actor, model and musician'

但实际输出是:

['an English actor, model and musician','film career by playing Cedric Diggory in Harry Potter']

【问题讨论】:

    标签: python regex python-3.x string


    【解决方案1】:

    由于您只希望从is 到句末,this RegEx 将起作用:

    \bis\s+(.+?)\.
    

    需要与标志s 一起使用,以便. 也匹配换行符,以防一个句子分布在多行中。我使用+ 量词和.,因为.* 将使整个正则表达式匹配,即使is. 之间没有任何内容,这对于一个句子没有意义。

    . 通过将其移出捕获括号而从您的输出中删除。 “句子的其余部分”在第一个捕获组中。

    请注意,如果句子中有Mrs. 之类的东西(并且有许多短语可能属于一个句子中包含.),那么这种简单的方法将不起作用。

    解析自然语言非常困难。如果你有 任何比简单、定义明确和可预测的文本更复杂的东西,那么您应该使用专门的库。例如,快速搜索会显示综合库 NLTKspaCy


    This helpful regex tool 解释了它是如何匹配的。您尝试的变体

    (\bis\b)([\s\S]*)
    

    有关详细信息,请参阅链接页面。评论

    • 它创建了两个捕获组,您的目标输出是第二个组,您可以使用 $2 调用它。

    • 第一组在您唯一的 is 实例周围创建一个单词边界。

    • 您可以使用 \ 转义任何特定于语言的元字符。

    【讨论】:

    【解决方案2】:

    您需要在is 周围使用单词边界,因此只有is 匹配整个单词,而不是部分匹配其他单词,例如它与his 匹配(这不是预期的)并使用此正则表达式,

    \bis\s+([^.]*)
    

    没有单词边界,即使his 也会匹配并为您提供您不想要的第二句话。

    Regex Demo

    试试这个修改后的 Python 代码,

    import re
    
    s = '''Robert is an English actor, model and musician.
    He started his film career by playing Cedric Diggory in Harry Potter.'''
    r = re.findall(r'\bis\s+([^.]*)',s)
    print(r)
    

    仅打印,

    ['an English actor, model and musician']
    

    【讨论】:

    • 问题中的预期输出包含点!
    • @AmirA.Shabani:非常容易处理。只需要使用[^.] 而不是. 让我更新我的帖子。你有鹰的眼睛:)
    • @AmirA.Shabani:已更新。立即检查。
    • 你只需要前导\b。尾随一个隐含在必须始终跟随is 的空格中
    • 那里不需要(?: ... )(非捕获组)...?总而言之r'\bis\s+([^.]+)' 应该没问题 --- 考虑到这一定是一个头脑简单的想法,忽略了所有语言问题,如Mrs. 等(+,因为那里必须有一些东西来表达一个合理的句子。)
    【解决方案3】:

    使用partition()可能更容易:

    splice = s.partition("is")[2]  # an English actor, model and musician. He started his film career by playing Cedric Diggory in Harry Potter.
    

    然后split():

    final = splice.split('.')[0]
    

    【讨论】:

    • 这个答案不正确。 1) OP 使用 regex. 明确提及 2) 输出不是“英国演员、模特和音乐家”
    【解决方案4】:

    这是因为.* 是贪婪的,并且如果可以(并且可以)匹配所有其余部分。

    由于您有新的行分隔,您可以根据需要使用它。 仅对该字符串使用正则表达式,您可以使用 Positive Lookbehind (?<=is) 来执行此操作。 将匹配但不包含在结果中

    s = '''Robert is an English actor, model and musician.
    He started his film career by playing Cedric Diggory in Harry Potter.'''
    r = re.findall(r'(?<=is).*\n',s)
    print(r)
    [' an English actor, model and musician.\n']
    
    猜你喜欢
    • 2018-12-14
    • 1970-01-01
    • 1970-01-01
    • 2016-12-22
    • 2021-09-01
    • 2011-02-01
    • 2016-06-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多