检查另一个字符串中是否存在多个字符串


378

如何检查数组中的任何字符串是否在另一个字符串中?

喜欢:

a = ['a', 'b', 'c']
str = "a123"
if a in str:
  print "some of the strings found in str"
else:
  print "no strings found in str"

该代码行不通,只是为了展示我想要实现的目标。


5
我感到惊讶的是,就性能而言,与编译的正则表达式相比,还没有任何答案,特别是与字符串的大小和要搜索的“针”的数量相比。
专利

3
@帕特,我并不感到惊讶。问题不在于性能。如今,大多数程序员更在意它的完成和可读性。性能问题是有效的,但问题不同。
盖特利

13
将str用作变量会造成混淆,并且可能会导致意外行为,因为它是保留字。见链接
聪明的家伙

regex效果[abc]也很好,如果要测试的候选对象超过两个,它将更快。但是,如果字符串是任意的,并且您事先不了解它们以构造正则表达式,则必须使用该any(x in str for x in a)方法。
smci

@CleverGuy是正确的,尽管它不是保留字,否则您将无法对其进行分配。它是内置的。
wjandrea

Answers:


717

您可以使用any

a_string = "A string is more than its parts!"
matches = ["more", "wholesome", "milk"]

if any(x in a_string for x in matches):

同样检查 找到了列表中的所有字符串,请使用all代替any


11
any()需要迭代。我不确定您使用的是哪个版本的Python,但在2.6中,您需要将参数[]放在any()周围。any([x在a中的x中的str中的x]],以便理解返回一个可迭代的。但是,也许更高版本的Python已经做到了。
emispowder 2013年

7
@Mark Byers:对不起,您的评论很晚,但是有没有办法打印找到的字符串?你会怎么做。谢谢。
Shankar Kumar

3
我不确定,如果a是列表,而str是要匹配的对象,那么x是什么?Python新手入门 :)
红色

2
@红色:您可以for x in a像“对于列表中的每个元素”一样阅读。因为a是字符串列表,并且x是该列表的元素,所以x是字符串(原始示例中为'a','b','c')
用户

6
@emispowder在Python 2.6.9中按原样对我来说效果很好。
MPlanchard

67

any()到目前为止,如果您想要的只是TrueFalse,那么这是最好的方法,但是如果您想具体了解哪些字符串匹配,则可以使用一些方法。

如果要进行第一个匹配(False默认为):

match = next((x for x in a if x in str), False)

如果要获得所有匹配项(包括重复项):

matches = [x for x in a if x in str]

如果要获取所有非重复的匹配项(不考虑顺序):

matches = {x for x in a if x in str}

如果要以正确的顺序获取所有非重复的匹配项:

matches = []
for x in a:
    if x in str and x not in matches:
        matches.append(x)

请添加最后一场比赛的示例
Oleg Kokorin '18

@OlegKokorin:它以找到它们的顺序来创建匹配字符串的列表,但是如果两个相同,则仅保留第一个。
zondo

使用an OrderedDict可能比列表更有效。请参阅“删除列表中的重复项”的答案
wjandrea

44

如果输入的字符串变长astr变长,则应小心。简单的解采用O(S *(A ^ 2)),其中S是的长度,str而A是中的所有字符串的长度之和a。为获得更快的解决方案,请查看用于字符串匹配的Aho-Corasick算法,该算法以线性时间O(S + A)运行。


Aho-Corasick还能找到子字符串而不是前缀吗?
RetroCode

1
一些Python Aho-Corasick库在这里这里
vorpal

23

只是为了增加一些多样性regex

import re

if any(re.findall(r'a|b|c', str, re.IGNORECASE)):
    print 'possible matches thanks to regex'
else:
    print 'no matches'

或者如果您的清单太长- any(re.findall(r'|'.join(a), str, re.IGNORECASE))


1
这适用于问题的给定用例。如果您搜索(*此操作失败,因为需要完成对正则表达式语法的引用。
guettli '16

2
如果需要,您可以使用对其进行转义'|'.join(map(re.escape, strings_to_match))。您可能re.compile('|'.join(...))也很高兴。
Artyer

12

您需要迭代a的元素。

a = ['a', 'b', 'c']
str = "a123"
found_a_string = False
for item in a:    
    if item in str:
        found_a_string = True

if found_a_string:
    print "found a match"
else:
    print "no match found"

2
是的,我知道该怎么做,但是与Marks的答案相比,那是可怕的代码。
jahmax

10
仅当您了解Mark的代码时。您遇到的问题是您没有检查数组的元素。有很多简洁的python方式可以完成您想要的工作,这将隐藏代码错误的本质。
西莫斯·坎贝尔,2010年

9
它可能是“可怕的代码”,但这正是any()所做的。另外,这会为您提供实际匹配的字符串,而any()只是告诉您存在匹配项。
alldayremix 2013年

4

jbernadas已经提到Aho-Corasick-Algorithm,以降低复杂性。

这是在Python中使用它的一种方法:

  1. 这里下载aho_corasick.py

  2. 将其与主Python文件放在同一目录中并命名 aho_corasick.py

  3. 使用以下代码尝试算法:

    from aho_corasick import aho_corasick #(string, keywords)
    
    print(aho_corasick(string, ["keyword1", "keyword2"]))

请注意,搜索区分大小写


3
a = ['a', 'b', 'c']
str =  "a123"

a_match = [True for match in a if match in str]

if True in a_match:
  print "some of the strings found in str"
else:
  print "no strings found in str"

1

这取决于上下文猜,如果你要检查,如单文字(任何一个字,E,W,..等)足够

original_word ="hackerearcth"
for 'h' in original_word:
      print("YES")

如果要检查original_word中的任何字符:请使用

if any(your_required in yourinput for your_required in original_word ):

如果要在那个original_word中输入所有想要的输入,请使用所有简单的输入

original_word = ['h', 'a', 'c', 'k', 'e', 'r', 'e', 'a', 'r', 't', 'h']
yourinput = str(input()).lower()
if all(requested_word in yourinput for requested_word in original_word):
    print("yes")

您的输入是什么?我可以认出两件事:正在寻找某物的句子。我正在寻找的单词数组。但是您描述了三个变量,而我无法理解第三个变量。
mayid

1

关于如何获取String中所有列表元素的更多信息

a = ['a', 'b', 'c']
str = "a123" 
list(filter(lambda x:  x in str, a))

1

一种出奇的快速方法是使用set

a = ['a', 'b', 'c']
str = "a123"
if set(a) & set(str):
    print("some of the strings found in str")
else:
    print("no strings found in str")

如果a不包含任何多个字符的值(在这种情况下,请使用上面any列出的值),则此方法有效。如果是这样,这是简单的指定为字符串:。aa = 'abc'


0
flog = open('test.txt', 'r')
flogLines = flog.readlines()
strlist = ['SUCCESS', 'Done','SUCCESSFUL']
res = False
for line in flogLines:
     for fstr in strlist:
         if line.find(fstr) != -1:
            print('found') 
            res = True


if res:
    print('res true')
else: 
    print('res false')

输出示例图像



0
data = "firstName and favoriteFood"
mandatory_fields = ['firstName', 'lastName', 'age']


# for each
for field in mandatory_fields:
    if field not in data:
        print("Error, missing req field {0}".format(field));

# still fine, multiple if statements
if ('firstName' not in data or 
    'lastName' not in data or
    'age' not in data):
    print("Error, missing a req field");

# not very readable, list comprehension
missing_fields = [x for x in mandatory_fields if x not in data]
if (len(missing_fields)>0):
    print("Error, missing fields {0}".format(", ".join(missing_fields)));
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.