python – Check if multiple strings exist in another string

The Question :

437 people think this question is useful

How can I check if any of the strings in an array exists in another string?

Like:

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"

That code doesn’t work, it’s just to show what I want to achieve.

The Question Comments :
  • I’m surprised there aren’t (yet) any answers comparing to a compiled regex in terms of perf, especially compared to size of the string and number of “needles” to search for.
  • @Pat I am not surprised. The question is not about performance. Today most programmers care more for getting it done and readability. The performance question is valid, but a different question.
  • Using str as a variable is confusing and may result in unexpected behavior as it is a reserved word; see link.
  • regex [abc] also works perfectly well and will be faster if there are more than a couple of candidates to test. But if the strings are arbitrary and you don’t know them in advance to construct a regex, you will have to use the any(x in str for x in a) approach.
  • @CleverGuy You’re right, though it’s not a reserved word, otherwise you wouldn’t be able to assign to it. It’s a builtin.

The Answer 1

831 people think this answer is useful

You can use any:

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

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

Similarly to check if all the strings from the list are found, use all instead of any.

The Answer 2

77 people think this answer is useful

any() is by far the best approach if all you want is True or False, but if you want to know specifically which string/strings match, you can use a couple things.

If you want the first match (with False as a default):

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

If you want to get all matches (including duplicates):

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

If you want to get all non-duplicate matches (disregarding order):

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

If you want to get all non-duplicate matches in the right order:

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

The Answer 3

46 people think this answer is useful

You should be careful if the strings in a or str gets longer. The straightforward solutions take O(S*(A^2)), where S is the length of str and A is the sum of the lenghts of all strings in a. For a faster solution, look at Aho-Corasick algorithm for string matching, which runs in linear time O(S+A).

The Answer 4

25 people think this answer is useful

Just to add some diversity with regex:

import re

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

or if your list is too long – any(re.findall(r'|'.join(a), str, re.IGNORECASE))

The Answer 5

13 people think this answer is useful

You need to iterate on the elements of 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"

The Answer 6

7 people think this answer is useful

A surprisingly fast approach is to use 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")

This works if a does not contain any multiple-character values (in which case use any as listed above). If so, it’s simpler to specify a as a string: a = 'abc'.

The Answer 7

4 people think this answer is useful

jbernadas already mentioned the Aho-Corasick-Algorithm in order to reduce complexity.

Here is one way to use it in Python:

  1. Download aho_corasick.py from here

  2. Put it in the same directory as your main Python file and name it aho_corasick.py

  3. Try the alrorithm with the following code:

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

Note that the search is case-sensitive

The Answer 8

3 people think this answer is useful
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"

The Answer 9

1 people think this answer is useful

It depends on the context suppose if you want to check single literal like(any single word a,e,w,..etc) in is enough

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

if you want to check any of the character among the original_word: make use of

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

if you want all the input you want in that original_word,make use of all simple

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")

The Answer 10

1 people think this answer is useful

Just some more info on how to get all list elements availlable in String

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

The Answer 11

0 people think this answer is useful
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')

output example image

The Answer 12

0 people think this answer is useful

I would use this kind of function for speed:

def check_string(string, substring_list):
    for substring in substring_list:
        if substring in string:
            return True
    return False

The Answer 13

0 people think this answer is useful
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)));

The Answer 14

0 people think this answer is useful

Yet another solution with set. using set.intersection. For a one-liner.

subset = {"some" ,"words"} 
text = "some words to be searched here"
if len(subset & set(text.split())) == len(subset):
   print("All values present in text")

if subset & set(text.split()):
   print("Atleast one values present in text")

The Answer 15

0 people think this answer is useful

The regex module recommended in python docs, supports this

words = {'he', 'or', 'low'}
p = regex.compile(r"\L<name>", name=words)
m = p.findall('helloworld')
print(m)

output:

['he', 'low', 'or']

Some details on implementation: link

The Answer 16

0 people think this answer is useful

A compact way to find multiple strings in another list of strings is to use set.intersection. This executes much faster than list comprehension in large sets or lists.

>>> astring = ['abc','def','ghi','jkl','mno']
>>> bstring = ['def', 'jkl']
>>> a_set = set(astring)  # convert list to set
>>> b_set = set(bstring)
>>> matches = a_set.intersection(b_set)
>>> matches
{'def', 'jkl'}
>>> list(matches) # if you want a list instead of a set
['def', 'jkl']
>>>

Add a Comment