【问题标题】:Capture the n previous words when matching a string匹配字符串时捕获前 n 个单词
【发布时间】:2021-05-04 04:17:31
【问题描述】:

假设我有这个文本:

abcdefg Mark Jones (PP) etc etc
akslaskAS Taylor Daniel Lautner (PMB) blabla
etcetc Allan Stewart Konigsberg Farrow (PRTW)

我想获取这些人名:

马克·琼斯、泰勒·丹尼尔·洛特纳、艾伦·斯图尔特·柯尼斯堡·法罗。

基本上,当我们发现 (P 后跟任何大写字母时,我们会捕获前面 n 个以大写字母开头的单词。

到目前为止,我所取得的成就是使用以下代码仅捕获一个先前的单词:\w+(?=\s+(\(P+[A-Z]))。但我无法从中进化。 如果有人可以提供帮助,我将不胜感激:)

【问题讨论】:

    标签: python regex


    【解决方案1】:

    正则表达式模式

    \b((?:[A-Z]\w+\s?)+)\s\(P[A-Z]
    

    为了找到上述正则表达式模式的所有匹配项,我们可以使用re.findall

    import re
    
    text = """abcdefg Mark Jones (PP) etc etc
    akslaskAS Taylor Daniel Lautner (PMB) blabla
    etcetc Allan Stewart Konigsberg Farrow (PRTW)
    """
    
    matches = re.findall(r'\b((?:[A-Z]\w+\s?)+)\s\(P[A-Z]', text)
    

    >>> matches
    ['Mark Jones', 'Taylor Daniel Lautner', 'Allan Stewart Konigsberg Farrow']
    

    正则表达式详细信息

    • \b:防止部分匹配的字边界
    • ((?:[A-Z]\w+\s?)+): 第一抓包组
      • (?:[A-Z]\w+\s?)+:非捕获组匹配一次或多次
        • [A-Z]:匹配从大写 AZ 的单个字母
        • \w+: 匹配任意单词字符一次或多次
        • \s? :匹配任何空白字符零次或一次
    • \s :匹配单个空白字符
    • \(:匹配字符 ( 字面意思
    • P :匹配字符 P 字面意思
    • [A-Z] :匹配从大写 AZ 的单个字母

    在线查看regex demo

    【讨论】:

    • 您的回答非常好!但我遇到了一个新问题:像“Juan di Lorenzo”或“Luca dos Santos”这样的名字没有被完全捕捉到,因为这些介词没有大写。我该如何解决?
    【解决方案2】:

    对于您显示的示例,您能否尝试以下操作。在此处使用 Python 的 re 库来获取结果。首先使用findall从给定的字符串var中获取所有值,其中(.*?)\s+\((?=P[A-Z])将捕获所有带有P和大写字母的内容,然后创建一个列表lst。稍后使用替换函数替换所有非空格的东西,然后用 NULL 替换第一次出现的空格以获得准确的值。

    import re
    var="""abcdefg Mark Jones (PP) etc etc
    akslaskAS Taylor Daniel Lautner (PMB) blabla
    etcetc Allan Stewart Konigsberg Farrow (PRTW)"""
    
    lst = re.findall(r'(.*?)\s+\((?=P[A-Z])',var)
    [re.sub(r'^\S+\s+','',s) for s in lst]
    

    输出如下:

    ['Mark Jones', 'Taylor Daniel Lautner', 'Allan Stewart Konigsberg Farrow']
    

    【讨论】:

    • 我认为只有findall 可以完成这项工作,只需从大写字母开始匹配即可。
    • @anubhava,谢谢先生您的好建议。我实际上考虑过,但后来我想如果有什么不是从大写字母开始的,所以我采用了这种方法。
    猜你喜欢
    • 2023-03-11
    • 1970-01-01
    • 2010-12-15
    • 2011-09-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多