title: Match an element only when it appears in the right half of the parsing string
body: <h3>The problem</h3>
  
  <p>I want to create a parser which matches strings like</p>
  
  <pre><code>"alpha beta 123 cpart"
  
   ----^----- -^- --^--
       A:      B:   C:
   alphanums  num alpha 
  </code></pre>
  
  <p>However the <strong>B</strong> part should only match when it appears in the second half of the string (i.e. to the 'right' of the string's mid-point).</p>
  
  <p>So the above sample string should be parsed into the parts:</p>
  
  <pre><code>A: ['alpha', 'beta']
  B: '123'
  C: ['cpart']
  </code></pre>
  
  <p>But the string <code>"123 alpha beta cpart"</code> should be parsed into:</p>
  
  <pre><code>A: '123 alpha beta cpart'
  B: ''
  C: ''
  </code></pre>
  
  <h3>First approximation with pyparsing</h3>
  
  <p>As a starting point with <a href="http://pyparsing.wikispaces.com/" rel="nofollow noreferrer"><code>pyparsing</code></a> I tried to use the <code>matchOnlyAtCol</code> function (thinking I could later provide a modified version which accepts a range instead of a single column). However I got stuck on some strange behaviour of <code>matchOnlyAtCol</code>. Here my demo code:</p>
  
  <pre><code>b_only_near_end = pp.Word(pp.nums)\
                      .setParseAction(pp.matchOnlyAtCol(12))('B')
  a = pp.ZeroOrMore(pp.Word(pp.alphanums), stopOn=b_only_near_end)('A')
  c = pp.ZeroOrMore(pp.Word(pp.alphas))('C')
  expr = a + pp.Optional(b_only_near_end) + c
  </code></pre>
  
  <p><strong>1)</strong> When I feed the first sample string <code>"alpha beta 123 cpart"</code> into <code>expr</code>'s <code>ParseString</code> I get the expected result</p>
  
  <pre><code>A: ['alpha', 'beta']
  B: '123'
  C: ['cpart']
  </code></pre>
  
  <p>because <strong>B</strong> starts exactly on column 12. </p>
  
  <p><strong>2)</strong> When I feed it the second string <code>"123 alpha beta cpart"</code> (part <strong>B</strong> on column 1) I get</p>
  
  <pre><code>ParseException:
  Expected end of text (at char 0), (line:1, col:1)
  "&gt;!&lt;123 alpha beta cpart"
  </code></pre>
  
  <p>Why? <code>b_only_near_end</code> should not match at all and therefore not stop the expression <code>a</code>, so I expect that <code>a</code> eats up all characters and I don't expect an exception to bubble up, because all parts are somehow optional (either via the <code>Optional</code> class or via the <code>ZeroOrMore</code> construct).</p>
  
  <hr>
  
  <h3>Update: What match debugging reveals</h3>
  
  <p>I switched  on debugging via <code>setDebug()</code> for the <code>ZeroOrMore</code> elements via the following expression code:</p>
  
  <pre><code>b_word = pp.Word(pp.nums).setName('_B_word_')
  b_word.setDebug()
  b_only_near_end = b_word\
                      .setParseAction(pp.matchOnlyAtCol(12))('B')
  a_word = pp.Word(pp.alphanums).setName('_A_word_')
  a_word.setDebug()
  a = pp.ZeroOrMore(a_word, stopOn=b_only_near_end).setName('__A__')('A')
  a.setDebug()
  
  c_word = pp.Word(pp.alphas).setName('_C_word_')
  c_word.setDebug()
  c = pp.ZeroOrMore(c_word).setName('__C__')('C')
  c.setDebug()
  
  expr = a + pp.Optional(b_only_near_end) + c
  </code></pre>
  
  <p><strong>1)</strong> When feeding in the string <code>"alpha beta 123 cpart"</code> I get as debug output:</p>
  
  <pre><code>Match __A__ at loc 0(1,1)
  Match _B_word_ at loc 0(1,1)
  Exception raised:Expected _B_word_ (at char 0), (line:1, col:1)
  Match _A_word_ at loc 0(1,1)
  Matched _A_word_ -&gt; ['alpha']
  Match _B_word_ at loc 5(1,6)
  Exception raised:Expected _B_word_ (at char 6), (line:1, col:7)
  Match _A_word_ at loc 5(1,6)
  Matched _A_word_ -&gt; ['beta']
  Match _B_word_ at loc 10(1,11)
  Matched _B_word_ -&gt; ['123']
  Matched __A__ -&gt; ['alpha', 'beta']
  Match _B_word_ at loc 11(1,12)
  Matched _B_word_ -&gt; ['123']
  Match __C__ at loc 14(1,15)
  Match _C_word_ at loc 15(1,16)
  Matched _C_word_ -&gt; ['cpart']
  Match _C_word_ at loc 20(1,21)
  Exception raised:Expected _C_word_ (at char 20), (line:1, col:21)
  Matched __C__ -&gt; ['cpart']
  </code></pre>
  
  <p><strong>2)</strong> With the string <code>"123 alpha beta cpart"</code> the output is:</p>
  
  <pre><code>Match __A__ at loc 0(1,1)
  Match _B_word_ at loc 0(1,1)
  Matched _B_word_ -&gt; ['123']
  Matched __A__ -&gt; []
  Match _B_word_ at loc 0(1,1)
  Exception raised:matched token not at column 12 (at char 0), (line:1, col:1)
  Match __C__ at loc 0(1,1)
  Match _C_word_ at loc 0(1,1)
  Exception raised:Expected _C_word_ (at char 0), (line:1, col:1)
  Matched __C__ -&gt; []
  </code></pre>
  
  <p>plus the ParseException:</p>
  
  <pre><code>Expected end of text (at char 0), (line:1, col:1)
  "&gt;!&lt;123 alpha beta cpart"
  </code></pre>
  
  <p>So this means part <strong>A</strong> matches the beginning of the string - with empty match result, because <code>a_word</code> does not match - So I guess I have to make <strong>A</strong> more greedy, but how?</p>
  
  <p>The strange thing is that </p>
  
  <pre><code>Matched __A__ -&gt; []
  </code></pre>
  
  <p>occurs before </p>
  
  <pre><code>Match _B_word_ at loc 0(1,1)
  Exception raised:matched token not at column 12 (at char 0), (line:1, col:1)
  </code></pre>
  
  <p><strong>A</strong> should "wait" with the match result longer, but how can i force it to do so?</p>
  
  <p>Maybe the whole approach is not fruitful? Is there another way to achieve matching only in the second part of a string?</p>