Check if a string contains all words of another string in the same order python?
<p>I want to check if a string contains all of the substring's words and retains their order; at the moment I am using the following code; However it is very basic, seems inefficient and likely there is a much better way of doing it. I'd really appreciate if you could tell me what a more efficient solution would be. Sorry for a noob question, I am new to the programming and wasn't able to find a good solution</p>

<pre><code>def check(main, sub_split):
    n=0
    while n &lt; len(sub_split):
        result = True
        if sub_split[n] in main:
            the_start =  main.find(sub_split[n])
            main = main[the_start:]

        else:
            result=False
        n += 1
    return result

a = "I believe that the biggest castle in the world is Prague Castle "
b= "the biggest castle".split(' ')

print check(a, b)
</code></pre>

<p>update: interesting; First of all thank you all for your answers. Also thank you for pointing out some of the spots that my code missed. I have been trying different solutions posted here and in the links, I will add update how they compare and accept the answer then.</p>

<p><strong>update:</strong>
Again thank you all for great solutions, every one of them had major improvements compared to my code; I checked the suggestions with my requirements for 100000 checks and got the following results;
suggestions by:
Padraic Cunningham - consistently under 0.4 secs (though gives some false positives when searching for only full words;
galaxyan - 0.65 secs; 0.75 secs
friendly dog - 0.70 secs
John1024 - 1.3 secs (Highly accurate, but seems to take extra time)</p>

<p>Let's define your <code>a</code> string and reformat your <code>b</code> string into a regex:</p>

<pre><code>&gt;&gt;&gt; a = "I believe that the biggest castle in the world is Prague Castle "
&gt;&gt;&gt; b = r'\b' + r'\b.*\b'.join(re.escape(word) for word in "the biggest castle".split(' ')) + r'\b'
</code></pre>

<p>This tests to see if the words in b appear in the same order in a:</p>

<pre><code>&gt;&gt;&gt; import re
&gt;&gt;&gt; bool(re.search(b, a))
True
</code></pre>

<p>Caveat: If speed is important, a non-regex approach may be faster.</p>

<h3>How it works</h3>

<p>The key thing here is the reformulation of the string into a regex:</p>

<pre><code>&gt;&gt;&gt; b = r'\b' + r'\b.*\b'.join(re.escape(word) for word in "the biggest castle".split(' ')) + r'\b'
&gt;&gt;&gt; print(b)
\bthe\b.*\bbiggest\b.*\bcastle\b
</code></pre>

<p><code>\b</code> matches only at word boundaries.  This means, for example, that the word <code>the</code> will never be confused with the word <code>there</code>.  Further, this regex requires that all the words be present in the target string in the same order.</p>

<p>If <code>a</code> contains a match to the regex <code>b</code>, then <code>re.search(b, a)</code> returns a match object.  Otherwise, it returns <code>None</code>. Thus, <code>bool(re.search(b, a))</code> returns <code>True</code> only if a match was found.</p>

<h3>Example with punctuation</h3>

<p>Because word boundaries treat punctuation as not word characters, this approach is not confused by punctuation:</p>

<pre><code>&gt;&gt;&gt; a = 'From here, I go there.'
&gt;&gt;&gt; b = 'here there'
&gt;&gt;&gt; b = r'\b' + r'\b.*\b'.join(re.escape(word) for word in b.split(' ')) + r'\b'
&gt;&gt;&gt; bool(re.search(b, a))
True
</code></pre>

python string python-2.7 substring