Python regex words boundary with unexpected results
<pre><code>import re
sstring = "ON Any ON Any"
regex1 = re.compile(r''' \bON\bANY\b''', re.VERBOSE)
regex2 = re.compile(r'''\b(ON)?\b(Any)?''', re.VERBOSE)
regex3 = re.compile(r'''\b(?:ON)?\b(?:Any)?''', re.VERBOSE)
for a in regex1.findall(sstring): print(a)
print("----------")
for a in regex2.findall(sstring): print(a)
print("----------")
for a in regex3.findall(sstring): print(a)
print("----------")
</code></pre>

<blockquote>
  <hr>
  
  <p>('ON', '')
  ('', '')
  ('', 'Any')
  ('', '')
  ('ON', '')
  ('', '')
  ('', 'Any')</p>
  
  <h2>('', '')</h2>
  
  <p>ON</p>
  
  <p>Any</p>
  
  <p>ON</p>
  
  <p>Any</p>
  
  <hr>
</blockquote>

<p>Having read many articles on the internet and S.O. I think I still don't understand the regex word boundary: <code>\b</code></p>

<p>The first regex doesn't give me the expected result I think it's must give me "ON Any On Any" but it still not give me that.</p>

<p>The second regex gives me tuples and I don't know why or understand the meaning of: ('', '')</p>

<p>The third regex gives prints the results on separated lines and empty lines in betweens</p>

<p>Could you please help me to understand that.</p>

<p>Note that to match <code>ON ANY</code> you need to add an escaped (since you are using <code>re.VERBOSE</code> flag) space between <code>ON</code> and <code>ANY</code> as <code>\b</code> word boundary <em>being a <strong>zero-width assertion</em></strong> does not consume any text, just asserts a position between specific characters. That is the reason for your first <code>re.compile(r''' \bON\bANY\b''', re.VERBOSE)</code> approach failure.</p>

<p>Use</p>

<pre><code>rx = re.compile(r''' \bON\ ANY\b ''', re.VERBOSE|re.IGNORECASE)
</code></pre>

<p>See the <a href="https://ideone.com/cBsGLd" rel="nofollow">Python demo</a></p>

<p>The <code>re.compile(r'''\b(ON)?\b(Any)?''', re.VERBOSE)</code> returns tuples since you defined <code>(...)</code> <em>capturing groups</em> in the pattern.</p>

<p>The <code>re.compile(r'''\b(?:ON)?\b(?:Any)?''', re.VERBOSE)</code> matches optional sequences, either <code>ON</code> or <code>Any</code>, so you get those words as values. You get empty values as well because this regex can match just a word boundary (all other subpatterns are optional).</p>

<p>More details about word boundaries:</p>

<ul>
<li><a href="http://www.regular-expressions.info/wordboundaries.html" rel="nofollow">Regular-Expressions.info</a></li>
<li><a class='doc-link' href="http://stackoverflow.com/documentation/regex/1539/word-boundary#t=201610051404594046741">SO Word Boundary Documentation</a></li>
<li><a href="http://stackoverflow.com/questions/21389837/java-regex-word-boundaries">Java Regex Word Boundaries</a> (this is still a word boundary in a regex, also applicable here)</li>
</ul>

python regex word-boundary