在Python中,我如何从列表中删除包含特定字符的元素?

22

如果这是一个简单的问题,我很抱歉,因为我还是很新手,但我已经花了一段时间寻找答案,但没有找到。我有一个看起来像这个可怕混乱的列表:

['Organization name} ', '> (777) 777-7777} ', ' class="lsn-mB6 adr">1 Address, MA 02114 } ', ' class="lsn-serpListRadius lsn-fr">.2 Miles} MORE INFO YOUR LISTING MAP if (typeof(serps) !== \'undefined\') serps.arrArticleIds.push(\'4603114\'); ', 'Other organization} ', '> (555) 555-5555} ', ' class="lsn-mB6 adr">301 Address, MA 02121 } ', ' class="lsn-serpListRadius lsn-fr">.2 Miles} MORE INFO CLAIM YOUR LISTING MAP if (typeof(serps) !== \'undefined\') serps.arrArticleIds.push(\'4715945\'); ', 'Organization} ']

我需要处理一段文本,使得HTML.py可以将其转换为表格。但是由于某些原因,HTML.py无法处理大量元素(例如'class="lsn-serpListRadius lsn-fr">.2 Miles} MORE INFO YOUR LISTING MAP if (typeof(serps) !== \'undefined\') serps.arrArticleIds.push(\'4603114\');'等)。幸运的是,我实际上并不关心这些元素中的信息,想要将它们删除。

我尝试编写一个正则表达式来匹配所有超过两个字母的大写字母单词,以识别这些巨型元素,并获得了以下结果:

re.compile('[^a-z]*[A-Z][^a-z]*\w{3,}')

但是我不知道如何将其应用于从列表中删除包含与该正则表达式匹配的元素。我该怎么做/这是正确的方法吗?

5个回答

32

我认为你的正则表达式不正确,如果要匹配包含三个或更多字符的全大写单词的所有条目,你应该像这样使用 re.search

regex = re.compile(r'\b[A-Z]{3,}\b')

有了这个,你可以使用列表推导式或内置的filter函数进行筛选:

full = ['Organization name} ', '> (777) 777-7777} ', ' class="lsn-mB6 adr">1 Address, MA 02114 } ', ' class="lsn-serpListRadius lsn-fr">.2 Miles} MORE INFO YOUR LISTING MAP if (typeof(serps) !== \'undefined\') serps.arrArticleIds.push(\'4603114\'); ', 'Other organization} ', '> (555) 555-5555} ', ' class="lsn-mB6 adr">301 Address, MA 02121 } ', ' class="lsn-serpListRadius lsn-fr">.2 Miles} MORE INFO CLAIM YOUR LISTING MAP if (typeof(serps) !== \'undefined\') serps.arrArticleIds.push(\'4715945\'); ', 'Organization} ']
regex = re.compile(r'\b[A-Z]{3,}\b')
# use only one of the following lines, whichever you prefer
filtered = filter(lambda i: not regex.search(i), full)
filtered = [i for i in full if not regex.search(i)]

以下列表中的结果(我认为这就是您要找的内容):

>>> pprint.pprint(filtered)
['Organization name} ',
 '> (777) 777-7777} ',
 ' class="lsn-mB6 adr">1 Address, MA 02114 } ',
 'Other organization} ',
 '> (555) 555-5555} ',
 ' class="lsn-mB6 adr">301 Address, MA 02121 } ',
 'Organization} ']

这两行代码的速度有区别吗? - NumenorForLife

9

首先,存储你的正则表达式,然后使用列表推导式:

regex = re.compile('[^a-z]*[A-Z][^a-z]*\w{3,}')
okay_items = [x for x in all_items if not regex.match(x)]

这似乎应该可以工作,但由于某种原因,当使用我的原始正则表达式时,它返回一个没有组织名称的列表,而当使用F.J的正则表达式时,它只是输出我输入的相同列表。不确定为什么。 - RSid

3

或者不使用编译正则表达式的方式:

from re import match

ll = ['Organization name} ', '> (777) 777-7777} ', ' class="lsn-mB6 adr">1 Address, MA 02114 } ', ' class="lsn-serpListRadius lsn-fr">.2 Miles} MORE INFO YOUR LISTING MAP if (typeof(serps) !== \'undefined\') serps.arrArticleIds.push(\'4603114\'); ', 'Other organization} ', '> (555) 555-5555} ', ' class="lsn-mB6 adr">301 Address, MA 02121 } ', ' class="lsn-serpListRadius lsn-fr">.2 Miles} MORE INFO CLAIM YOUR LISTING MAP if (typeof(serps) !== \'undefined\') serps.arrArticleIds.push(\'4715945\'); ', 'Organization} ']

filteredData = [x for x in ll if not match(r'[^a-z]*[A-Z][^a-z]*\w{3,}', x)]

编辑:

from re import compile

rex = compile('[^a-z]*[A-Z][^a-z]*\w{3,}')
filteredData = [x for x in ll if not rex.match(x)]

如果您将对列表中的许多项运行相同的正则表达式,则应该编译它。尽管Python通常足够聪明,可以为您编译并缓存它,但最好是显式地编译它。 - Amber

1

不使用正则表达式

def isNotMonster(x):
    return not any((len(word) > 2) and (word == word.upper()) for word in x.split())

okay_items = filter(isNotMonster, all_items)

这只返回组织的名称 - 实际上对我现在也有帮助,所以另外感谢,但这不是我要找的。 - RSid

0
element = 'string_to_search'
for item in y_list_of_items:
    if element in item:
        y_list_of_items.remove(item)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接