我正在使用Python,我想匹配一个给定的字符串与多个子字符串。我试图用两种不同的方法解决这个问题。我的第一个解决方案是将子字符串与字符串匹配,如下所示:
str = "This is a test string from which I want to match multiple substrings"
value = ["test", "match", "multiple", "ring"]
temp = []
temp.extend([x.upper() for x in value if x.lower() in str.lower()])
print(temp)
这导致temp = ["TEST", "MATCH", "MULTIPLE", "RING"]
。
但是,这不是我想要的结果,子字符串应该有精确的匹配,所以“环”不应该与“字符串”匹配。
这就是为什么我试图用正则表达式来解决这个问题,就像这样:
str = "This is a test string from which I want to match multiple substrings"
value = ["test", "match", "multiple", "ring"]
temp = []
temp.extend([
x.upper() for x in value
if regex.search(
r"\b" + regex.escape(x) + r"\b", str, regex.IGNORECASE
) is not None
])
print(temp)
这导致["TEST", "MATCH", "MULTIPLE"]
,正确的解决方案。
尽管如此,这个解决方案的计算时间太长了。我必须对大约100万个字符串进行检查,使用正则表达式的解决方案需要几天才能完成,而使用第一个解决方案需要1.5小时。
有没有办法让第一个解决方案工作,或者让第二个解决方案运行得更快?value
也可以包含数字,或者像“test1 test2”这样的短语。
4条答案
按热度按时间9w11ddsr1#
在没有看到实际数据的情况下,很难提出最佳解决方案,但您可以尝试以下方法:
'^'
或'*'
)。list.extend()
。kq4fsx7k2#
我想到了两种可能的优化:
re.compile
预编译模式,这样每次调用match
时它就不会重新编译。结果:
这种方法的潜在缺点:
values
中出现的顺序放置。这种方法将结果按它们在str
中出现的顺序放置。str
中出现多次,则它将在temp
中出现多次。与您最初的方法相反,该值在temp
中最多出现一次。search
在找到匹配项后立即终止。findall
总是搜索整个字符串。如果您希望大多数字符串匹配value
中的每个单词,并且希望大多数匹配项出现在字符串的早期,那么findall
可能比search
慢。另一方面,如果您希望搜索经常出现None
,那么findall
将可能稍微更快。ycggw6v23#
您可以按空格分割字符串,然后将
value
中的元素与==
匹配。你说
values
中的一些字符串可以在它们之前或之后有空格。你可以用这行来解决这个问题:这将删除字符串前后的所有空白字符(在您的情况下,每个元素都是空白字符)。
此外,你提到如果你按空格分割字符串,一些单词会有分割后留下的标点符号,例如
'Hi, how are you?'
会导致['Hi,', 'how', 'are', 'you?']
。你可以通过使用字符串startswith()
方法来过滤所有以values
中的元素开头的单词来解决这个问题,如下所示:然后你可以用正则表达式从结果列表中删除标点符号,但是现在你需要迭代的列表要小得多。在你删除所有标点符号字符之后,你就可以像我建议的那样匹配整个字符串了。
ylamdve64#
在我的笔记本电脑上使用以下代码执行100万次'statement'变量大约需要3秒: