如何检查一行是不是有列表中的一个字符串? [复制]

Posted

技术标签:

【中文标题】如何检查一行是不是有列表中的一个字符串? [复制]【英文标题】:How to check if a line has one of the strings in a list? [duplicate]如何检查一行是否有列表中的一个字符串? [复制] 【发布时间】:2012-01-24 21:34:04 【问题描述】:

可能重复:Check if multiple strings exist in another string

我正在尝试找出是否有一种很好且干净的方法来测试 3 个不同的字符串。

基本上,我使用for 循环遍历文件;然后我必须检查它是否包含我在列表中设置的 3 个字符串中的 1 个。

目前我发现了多重if条件检查,但感觉不是真的优雅高效:

for line in file
    if "string1" in line or "string2" in line or "string3" in line:
        print "found the string"

我想创建一个包含 string1string2string3 的列表,并检查其中是否包含其中任何一个,但似乎我不能只比较列表而不显式循环遍历列表,在这种情况下,我基本上处于与上面编写的多重 if 语句相同的条件。

有没有什么聪明的方法可以检查多个字符串,而无需编写长 if 语句或循环遍历列表的元素?

【问题讨论】:

你需要搜索每一行还是只找到第一行?如果是这样,您可以通过跳出 for 循环进行优化。 【参考方案1】:
strings = ("string1", "string2", "string3")
for line in file:
    if any(s in line for s in strings):
        print "yay!"

【讨论】:

虽然any 的含义很合乎逻辑,但我从未使用过它,所以我不得不查一下。不错的代码@Niklas。 这几乎完全相同。 这是一个函数。所有any 所做的只是检查序列中的任何值是否为真。真正的魔力是为序列使用生成器表达式。 @Niklas B.:很抱歉评论晚了,但是有没有办法打印找到的字符串?你会怎么做。谢谢。 @Pitto:啊,我现在才看到您的评论是对 Shabkar 的回应 :) 但是,line 不是找到的字符串。那将是 string 的匹配元素【参考方案2】:

这仍然循环通过两个列表的笛卡尔积,但它只做一行:

>>> lines1 = ['soup', 'butter', 'venison']
>>> lines2 = ['prune', 'rye', 'turkey']
>>> search_strings = ['a', 'b', 'c']
>>> any(s in l for l in lines1 for s in search_strings)
True
>>> any(s in l for l in lines2 for s in search_strings)
False

这还具有any 短路的优点,因此一旦找到匹配项,循环就会停止。此外,这只会在linesX 中找到来自search_strings 的字符串的第一次出现。如果您想查找多个匹配项,您可以执行以下操作:

>>> lines3 = ['corn', 'butter', 'apples']
>>> [(s, l) for l in lines3 for s in search_strings if s in l]
[('c', 'corn'), ('b', 'butter'), ('a', 'apples')]

如果您想编写更复杂的代码,Aho-Corasick 算法似乎可以测试给定输入字符串中是否存在多个子字符串。 (感谢 Niklas B. 指出这一点。)我仍然认为它会为您的用例带来二次性能,因为您仍然需要多次调用它来搜索多行。但是,它会击败上述(三次,平均)算法。

【讨论】:

其实有。查看 Aho-Corasick 自动机。它可以在线性时间内完成 @NiklasB.,谢谢,这很有趣!如果我错了,请纠正我,但我认为结果仍然是二次的,因为 OP 想要测试多行的子字符串匹配。但这仍然胜过幼稚的 any 版本(三次,假设平均 O(n) 性能为 in)。 不,它是线性的。构建自动机是线性时间,将字符串输入自动机也是线性时间 或者更准确地说,你用针构建了一次自动机,然后在每一行重复使用它 我以为自动机是用针做的……【参考方案3】:

一种方法是将搜索字符串组合成一个正则表达式模式,如this answer。

【讨论】:

我认为正则表达式更漂亮,但正则表达式不是有很多开销吗?它真的比简单的'if ... or ... or ...:'更有效吗? @SamRedway 有一些开销,但另一方面,搜索字符串可以组合成一个“一次性”处理的模式。 @SamRedway 嗯,好的,快速测试使正则表达式看起来很糟糕 所以我猜想在大多数用例中,可读性比效率更重要,这是基于该指标的完全合理的方法。会说“更有效”可能会产生误导。 @SamRedway 是的,现在编辑了。

以上是关于如何检查一行是不是有列表中的一个字符串? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

如何进行`if`检查键入的单词是不是等于C中字符串列表中的某个单词? [复制]

如何检查数组列表是不是包含特定的字符串值? [复制]

R - 对于数据框中的每一行,如何检查是不是至少有一列不是 NA? [复制]

如何使用条件检查列表中是不是存在字符串类型的输入? [复制]

如何检查一个字符串数组是不是包含 JavaScript 中的一个字符串? [复制]

Shell如何检查文件中的一行中是不是存在模式