Non-greedy matching of Word in pyparsing?
<p>I would like to match a word that ends with either <code>_foo</code> or <code>_bar</code>. I wrote this: </p>

<pre><code>identifier = Word(alphanums + '_')
string     = identifier + Suppress('_') + oneOf('foo bar')
</code></pre>

<p>Unfortunately, I realized <code>identifier</code> is greedy and consume all the keyword. </p>

<p>How do I force <code>identifier</code> to be not greedy?</p>

<pre><code>$ string.parseString('a_keyword_foo')
ParseException: Expected "_" (at char 13), (line:1, col:14)
</code></pre>

<p>Some valid keywords:</p>

<pre><code>a_keyword_foo          # ['a_keyword', 'foo']
foo_bar_foo            # ['foo_bar',   'foo']
bar_bar                # ['bar',       'bar']
</code></pre>

<p>Some invalid keywords:</p>

<pre><code>keyword_foo_foobar
2keywords_bar          # The leading number is perhaps another question...
foo _bar 
_foo
</code></pre>

<p>If you have to/can switch to the re api you can use non-greedy matching there:</p>

<pre><code>    import re
    p = re.compile (r"""([a-z_]+?)        # lazy matching identifier
                         _ (bar|foo)      # _ with foo or bar
       """, re.VERBOSE)
    subject_string = 'a_hello_foo'
    m = p.match( subject_string )
    print "groups:", m.groups()
    print "group 1:", m.group(1)
</code></pre>

<p>Within pyparsing there is also the possibility to use regex.</p>

python pyparsing non-greedy