【问题标题】:Iterate and match all elements with regex使用正则表达式迭代并匹配所有元素
【发布时间】:2018-03-07 22:00:45
【问题描述】:

所以我有这样的事情:

data = ['Alice Smith and Bob', 'Tim with Sam Dunken', 'Uncle Neo & 31']

我想用名字替换每个元素,所以它看起来像这样:

data = ['Alice Smith', 'Tim', 'Uncle Neo']

到目前为止,我得到了:

for i in range(len(data)):
    if re.match('(.*) and|with|\&', data[i]):
        a = re.match('(.*) and|with|\&', data[i])
        data[i] = a.group(1)

但这似乎不起作用,我认为这是因为我的模式,但我无法找到正确的方法来做到这一点。

【问题讨论】:

  • 这不是替换。
  • 您的代码中的错误是您需要将and|with|\& 分组=> (and|with|\&)。否则,提供的答案会为您提供替代方法(更简单的方法)。

标签: python regex match


【解决方案1】:

简介

如果可能,我建议使用 Casimir 的答案,但是,如果您不确定后面可能会出现什么词(也就是说 andwith& 是动态的),那么您可以使用这个正则表达式。

注意:此正则表达式不适用于某些特殊情况,例如带有撇号 ' 或破折号 - 的名称,但您可以将它们添加到您正在搜索的字符列表中。这个答案还取决于以大写字符开头的名称和不以大写字符开头的“联合词”(andwith& 等)。


代码

See this regex in use here

正则表达式

^((?:[A-Z][a-z]*\s*)+)\s.*

替换

$1

结果

输入

Alice Smith and Bob
Tim with Sam Dunken
Uncle Neo & 31

输出

Alice Smith
Tim
Uncle Neo

说明

  • 在字符串的开头断言位置^
  • 匹配大写字母[A-Z]
  • 匹配任意数量的小写字母[a-z]*
  • 匹配任意数量的空白字符(如果您更喜欢使用*,可以指定空格)\s*
  • 在一次和无限次之间匹配上述条件,全部被捕获到捕获组 1 (...)+:其中 ... 包含上述所有内容
  • 匹配一个空白字符,后跟任意字符(换行除外)任意次数
  • $1:替换为捕获组 1

【讨论】:

    【解决方案2】:

    简化以下方法:

    import re
    
    data = ['Alice Smith and Bob', 'Tim with Sam Dunken', 'Uncle Neo & 31']
    data = [re.search(r'.*(?= (and|with|&))', i).group() for i in data]
    
    print(data)
    

    输出:

    ['Alice Smith', 'Tim', 'Uncle Neo']
    

    • .*(?= (and|with|&)) - 肯定的前瞻断言,确保名称/姓氏 .* 后跟来自交替组 (and|with|&) 的任何项目

    【讨论】:

    • 你能解释一下 ?= 的作用吗?谢谢。
    • @efsee,是的,看我的笔记
    【解决方案3】:

    你可以试试这个:

    import re
    data = ['Alice Smith and Bob', 'Tim with Sam Dunken', 'Uncle Neo & 31']
    final_data = [re.sub('\sand.*?$|\s&.*?$|\swith.*?$', '', i) for i in data]
    

    输出:

    ['Alice Smith', 'Tim', 'Uncle Neo']
    

    【讨论】:

      【解决方案4】:

      | 在您的尝试中需要用括号分组。反正太复杂了。

      我只会使用re.sub 来删除分隔词和其余部分:

      data = [re.sub(" (and|with|&) .*","",d) for d in data]
      

      结果:

      ['Alice Smith', 'Tim', 'Uncle Neo']
      

      【讨论】:

        【解决方案5】:

        在 re.split 中使用列表推导:

        result = [re.split(r' (?:and|with|&) ', x)[0] for x in data]
        

        【讨论】:

        • 如果我愿意,我可以这样做结果 = [re.split(r' (?:and|with|&) ', x)[0].lower() for x in data]同时将所有内容都小写?
        猜你喜欢
        • 1970-01-01
        • 2010-11-16
        • 1970-01-01
        • 2021-03-06
        • 1970-01-01
        • 1970-01-01
        • 2021-06-16
        • 2015-05-21
        • 1970-01-01
        相关资源
        最近更新 更多