Check if string contains a certain amount of words of another string
Question: Say we have a string 1 `A B C D E F` and a string 2 `B D E` (The letters are
just for demo, in reality they are words). Now I would like to find out if
there are any `n` conscutive "words" from string 2 in string 1. To convert the
string to "words", I'd use `string.split()`.

For example for `n` equals 2, I would like to check whether `B D` or `D E` is
- **in this order** \- in string 1. `B D` is not in this order in the string,
but `D E` is.

Does anyone see a pythonic way of doing this?

I do have a solution for `n` equals 2 but realized that I need it for
arbitrary n. Also it is not particularily beautiful:

    
    
    def string_contains_words_of_string(words_str, words_to_check_str):
        words = words_str.split()
        words_to_check = words_to_check_str.split()
    
        found_word_index = None
        for word in words:
            start = 0 if found_word_index is None else found_word_index + 1
            for i, word_to_check in enumerate(words_to_check[start:]):
                if word_to_check == word:
                    if found_word_index is not None:
                        return True
                    found_word_index = i
                    break
                else:
                    found_word_index = None
        return False
    


Answer: This is easy with a regex:

    
    
    >>> import re
    >>> st1='A B C D E F'
    >>> st2='B D E'
    >>> n=2
    >>> pat=r'(?=({}))'.format(r's+'.join(r'\w+' for i in range(n)))
    >>> print [(s, s in st1) for s in re.findall(pat, st2)]
    [('B D', False), ('D E', True)]
    

The key is to use a zero width look ahead to find overlapping matches in the
string. So:

    
    
    >>> re.findall('(?=(\\w+\\s+\\w+))', 'B D E')
    ['B D', 'D E']
    

Now build that for `n` repetitions of the word found by `\w+` with:

    
    
    >>> n=2
    >>> r'(?=({}))'.format(r's\+'.join(r'\w+' for i in range(n)))
    '(?=(\\w+\\s+\\w+))'
    

Now since you have two strings, use Python's `in` operator to produce a tuple
of the result of `s` from the regex matches to the target string.

* * *

Of course if you want a non-regex to do this, just produce substrings n words
by n:

    
    
    >>> li=st2.split()
    >>> n=2
    >>> [(s, s in st1) for s in (' '.join(li[i:i+n]) for i in range(len(li)-n+1))]
    [('B D', False), ('D E', True)]
    

And if you want the index (either method) you can use
[str.find](https://docs.python.org/2/library/stdtypes.html#str.find):

    
    
    >>> [(s, st1.find(s)) for s in (' '.join(li[i:i+n]) for i in range(len(li)-n+1)) 
    ...     if s in st1]
    [('D E', 6)]
    

* * *

For regex that goes word by word, make sure you use a word boundary anchor:

    
    
    >>> st='wordW wordX wordY wordZ'
    >>> re.findall(r'(?=(\b\w+\s\b\w+))', st)
    ['wordW wordX', 'wordX wordY', 'wordY wordZ']
    

