【问题标题】:How to exclude one word from python list?如何从 python 列表中排除一个单词?
【发布时间】:2016-06-28 19:15:41
【问题描述】:

我正在尝试使用 Python 正则表达式。我有一个清单如下:

['MYTAB-EVENTS', 'MYTAB-1', 'MYTAB-2', 'MYTAB-PERF','ABC','DEF']

我需要选择所有以MYTAB 开头的值,不包括MYTAB-2。 结果应该是:

['MYTAB-EVENTS', 'MYTAB-1', 'MYTAB-PERF']

它的正则表达式语法应该是什么?

【问题讨论】:

  • 问题需要澄清一下:像MYTAB-23 这样的东西有效吗?即,MYTAB-2 是禁止作为整个值还是仅作为前缀?

标签: python regex list


【解决方案1】:

你可以使用这段代码。

  1. 它将遍历初始列表l1,如果项目startswith("MYTAB"),它将被添加到列表l2
  2. 它会在l2列表中找到MYTAB-2的索引
  3. 删除MYTAB-2

代码:

l1 = ['MYTAB-EVENTS', 'MYTAB-1', 'MYTAB-2', 'MYTAB-PERF','ABC','DEF']
l2 = []

for item in l1:
    #add item to l2 if startswith MYTAB
    if item.startswith('MYTAB'):
        l2.append(item)

#getting index of 'MYTAB-2'
index = l2.index('MYTAB-2')

#removing MYTAB-B
del(l2[index])

#printing l2
l2

输出:

['MYTAB-EVENTS', 'MYTAB-1', 'MYTAB-PERF']

【讨论】:

  • @MadPhysicist 我正在展示解决他问题的另一种方法。这样我们都可以学习。你真的认为你需要对此投反对票吗?
  • 既然你已经添加了一些叙述,我非常愿意删除我的反对票。
【解决方案2】:

在列表理解上使用带有re 的过滤器:

import re

l = ['MYTAB-EVENTS', 'MYTAB-1', 'MYTAB-2', 'MYTAB-PERF','ABC','DEF']
l = [i  for i in l if re.match(r'MYTAB-[^2]', i)]
print(l)
# ['MYTAB-EVENTS', 'MYTAB-1', 'MYTAB-PERF']

【讨论】:

    【解决方案3】:
    >>> import re
    >>> list_ = ['MYTAB-EVENTS', 'MYTAB-1', 'MYTAB-2', 'MYTAB-PERF', 'ABC', 'DEF']
    >>> filtered_list = filter(lambda str_: re.search(r'^MYTAB(?!-2)', str_), list_)
    >>> filtered_list
    ['MYTAB-EVENTS', 'MYTAB-1', 'MYTAB-PERF']
    

    【讨论】:

    • 你可以去掉前面的^,用match代替search。 +1 表示负前瞻。
    • @MadPhysicist 我同意你的观点,但我这样做是为了显示更多正则表达式语法,例如提问者提问。
    • 越多越好。我没有看到 OP 在哪里要求更复杂的正则表达式。
    • @MadPhysicist “我需要选择所有以 ... 开头的值,它的正则表达式语法应该是什么?”对我来说,^.match() 更能说明正则表达式语法
    • 很公平。这只是一个细节。不管怎样,我都投了赞成票,因为到目前为止,消极的前瞻是最好的方法。
    【解决方案4】:

    您有许多用于过滤列表的选项。如果您使用的是re.match,则您的问题的基本答案是'MYTAB(?!-2)',它与输入的开头相匹配。

    import re
    expr = re.compile('MYTAB(?!-2)')
    rawList = ['MYTAB-EVENTS', 'MYTAB-1', 'MYTAB-2', 'MYTAB-PERF','ABC','DEF']
    filteredList = [x for x in rawList if expr.match(x)]
    

    但是,由于您正在查看前缀,因此有一种更简单的方法:

    filteredList = [x for x in rawList if x.startswith('MYTAB') and x not x.startswith('MYTAB-2')]
    

    如果您因任何原因对列表推导不满意,您可能需要使用内置的 filter 函数:

    filteredList = list(filter(expr.match, rawList))
    

    甚至

    filteredList = list(filter(lambda x: x.startswith('MYTAB') and not x.startswith('MYTAB-2'), rawList))
    

    此外,如果您不希望保留对预编译表达式的引用(例如,为了简洁起见,交易效率),您可以使用 re.match 而不是 re.compile.match

    import re
    rawList = ['MYTAB-EVENTS', 'MYTAB-1', 'MYTAB-2', 'MYTAB-PERF','ABC','DEF']
    filteredList = [x for x in rawList if re.match(x)]
    

    【讨论】:

      【解决方案5】:

      您可以为此使用正则表达式/MYTAB-[^2]+/。语法[^2] 表示除2 之外的所有内容。

      【讨论】:

      • [^2]+ 加号强制引擎匹配不是2 的所有其他字符,因此MYTAB-22MYTAB-2 不同,它不会被匹配。
      【解决方案6】:

      尝试使用 pyregex 查找您的正则表达式搜索。这是一个link 到您的问题的工作正则表达式

      在这种情况下,它使用MYTAB-[^2] 作为正则表达式模式。

      【讨论】:

      • 仅链接答案。请把它的肉贴在这里。
      猜你喜欢
      • 1970-01-01
      • 2020-02-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-09
      相关资源
      最近更新 更多