检查部分字符串列表是否在单个字符串内?

时间:2019-02-28 04:59:49

标签: python python-2.7

希望同一个问题尚未得到回答(我看过但找不到)。

我有一个部分字符串列表:

date_parts = ['/Year', '/Month', '/Day',....etc. ]

,我有一个字符串。 例如

string1 = "Tag01/Source 01/Start/Year"

string1 = "Tag01/Source 01/Volume"

除了使用for循环以外,最有效的方法是检查字符串中是否包含任何date_parts字符串?

有关信息,实际上string1实际上是许多字符串的另一个列表,我想删除date_parts列表中包含字符串的所有这些字符串。

2 个答案:

答案 0 :(得分:1)

您可以将any函数用于列表理解。它应该比for循环快一点。

对于一个字符串,您可以像这样进行测试:

any(p in string1 for p in date_parts)

如果strings是要检查的许多字符串的列表,则可以执行以下操作:

unmatched = [s for s in strings if not any(p in s for p in date_parts)]

unmatched = [s for s in strings if all(p not in s for p in date_parts)]

答案 1 :(得分:1)

根据部分字符串编译一个正则表达式。如果re.escape()包含正则表达式语言中的控制字符,请使用。

import re
date_parts = ['/Year', '/Month', '/Day']
pattern = re.compile('|'.join(re.escape(s) for s in date_parts))

然后使用re.search()查看它是否匹配。

string1 = "Tag01/Source 01/Start/Year"
re.search(pattern, string1)

regex引擎可能比本地Python循环更快。


对于您的特定用例,请考虑串联所有字符串,例如

all_string = '\n'.join(strings+[''])

然后,您只需一次调用regex引擎就可以一次完成所有操作。

pattern = '|'.join(f'.*{re.escape(s)}.*\n' for s in date_parts)
strings = re.sub(pattern, '', all_string).split('\n')[:-1]

当然,这假定您的所有字符串都没有'\n'。您可以选择字符串中没有的其他字符进行合并和拆分(如有必要)。例如,'\f'应该很少见。使用'@'的方法如下。

all_string = '@'.join(strings+[''])
pattern = '|'.join(f'[^@]*{re.escape(s)}[^@]*@' for s in date_parts)
strings = re.sub(pattern, '', all_string).split('@')[:-1]

如果那还不够快,您可以尝试使用更快的正则表达式引擎,例如rure