 <p>I'm a bit confused by your double capturing group, and the fact that you're using <code>\w</code> but want to match a non-word character like <code>&amp;</code> (maybe you mean <code>\S</code>, non-spaces, where you say <code>\w</code>...?), but, maybe...:</p> <pre><code>&gt;&gt;&gt; import re &gt;&gt;&gt; r = re.compile(r'(?P&lt;words&gt;\w+(?:\s+\S+)*?)\s*(?P&lt;num&gt;\d+)?\r\n') &gt;&gt;&gt; for s in ('Foo &amp; Bar 555\r\n', 'Hello World\r\n', 'Spam 99\r\n', ... 'Number 1 666\r\n'): ... print s, r.match(s).groupdict() ... Foo &amp; Bar 555 {'num': '555', 'words': 'Foo &amp; Bar'} Hello World {'num': None, 'words': 'Hello World'} Spam 99 {'num': '99', 'words': 'Spam'} Number 1 666 {'num': '666', 'words': 'Number 1'} &gt;&gt;&gt; </code></pre>