【问题标题】:Searching string for different substrings在字符串中搜索不同的子字符串
【发布时间】:2013-08-19 18:11:36
【问题描述】:

我有一个字符串。我需要知道字符串中是否出现以下任何子字符串。

所以,如果我有:

thing_name = "VISA ASSESSMENTS"

我一直在搜索:

any((_ in thing_name for _ in ['ASSESSMENTS','KILOBYTE','INTERNATIONAL']))

我正在浏览一长串 thing_name 项目,我不需要过滤,确切地说,只需检查任意数量的子字符串。

这是最好的方法吗?感觉不对,但我想不出更有效的方法来解决这个问题。

【问题讨论】:

  • 您是在搜索确切的词 VISAASSESSMENTS 还是任何子字符串?
  • 如果您的可能子字符串列表是一组,您可能会加快速度,但除此之外,我认为这种方法没有任何问题。这很好,可读。下一步将是认真的算法设计。
  • @AshwiniChaudhary,我正在寻找“评估”、“千字节”或其他几个项目之一。
  • @kojiro,谢谢。我会进行一些速度测试。
  • @JoshEnglish 我不知道您的初始数据,但它可能值得消除子字符串 within 集合:例如,如果您有{'foo', 'bar', 'foobaz'} 你可以从集合中删除 foobaz

标签: python string substring


【解决方案1】:

您可以尝试re.search 看看是否更快。类似于

import re
pattern = re.compile('|'.join(['ASSESSMENTS','KILOBYTE','INTERNATIONAL']))
isMatch = (pattern.search(thing_name) != None)

【讨论】:

  • 谢谢大家的建议。因此,我做了一些时间安排,发现重新解决方案在我的情况下是最快的。我想出了八种不同的方法来做到这一点,并从我的情况中获取数据,考虑到字段的长度和数量,RE 是最快的。预编译正则表达式是最好的,其次是在每次运行我的列表时编译正则表达式。 Set 交集是第三快的,但是当检查 set 的长度并与 0 进行比较时,比简单地将交集转换为布尔值更快。
  • 我建议在将子字符串传递给re.compile(即re.compile('|'.join(re.escape(sub) for sub in [...])))之前在子字符串上使用re.escape,否则包含非字母数字字符的子字符串可能会产生问题(它甚至可以导致re.compile 失败)。
  • @Bakuriu,+1 分享re.escape
【解决方案2】:

如果您的子字符串列表很小并且输入很小,那么使用 for 循环进行比较就可以了。

否则,我知道在字符串中搜索(大)子字符串列表的最快方法是构造单词列表的 DAWG,然后遍历输入字符串,保留 DAWG 遍历列表并在每个位置注册子字符串成功穿越。

另一种方法是将所有子字符串添加到哈希表中,然后在遍历输入字符串时对每个可能的子字符串(最长子字符串的长度)进行哈希处理。

自从我在 python 中工作已经有一段时间了,我的记忆是在其中实现东西很慢。要走 DAWG 路线,我可能会将它实现为原生模块,然后在 python 中使用它(如果可能的话)。否则,我会先做一些速度检查来验证,但可能会走哈希表路线,因为 python 中已经有高性能的哈希表。

【讨论】:

猜你喜欢
  • 2019-10-06
  • 1970-01-01
  • 1970-01-01
  • 2021-04-25
  • 2011-07-04
  • 1970-01-01
  • 1970-01-01
  • 2017-02-09
相关资源
最近更新 更多