<p>正则表达式量词在默认情况下是“贪婪的”,这意味着它们将尽可能地“吃”。你知道吗</p>
<pre><code>[\s\w\.\-]+
</code></pre>
<p>表示查找至少一个且尽可能多的空格、单词、点或破折号字符。向前看防止它吃掉整个输入(实际上regex引擎会吃掉整个输入,然后根据需要开始后退),这意味着它吃掉每个文件规范行,除了最后一行(向前看坚持必须留下)。你知道吗</p>
<p>添加一个?在量词(*)之后?, +?, ??,等等)使量词“懒惰”或“不情愿”。这将“+”的含义从“匹配至少一个且尽可能多”更改为“匹配至少一个且不超过所需”。你知道吗</p>
<p>所以把最后一个+改成a+?应该能解决你的问题。你知道吗</p>
<p>问题不在于向前看,它工作得很好,而在于它前面的最后一个子表达式。你知道吗</p>
<p>编辑:</p>
<p>即使进行了此更改,正则表达式也不会解析最后一行文件规范。这是因为正则表达式坚持文件名后面必须有权限规范。要解决这个问题,我们必须允许前瞻性不匹配(但要求它在除最后一个规范之外的所有方面都匹配)。进行以下更改将解决此问题</p>
<pre><code>ftp_list_re = compile('(?P<permissions>[d-][rwx-]{9})[\s]{1,20}'
'(?P<links>[0-9]{1,8})[\s]{1,20}'
'(?P<owner>[0-9A-Za-z_-]{1,16})[\s]{1,20}'
'(?P<group>[0-9A-Za-z_-]{1,16})[\s]{1,20}'
'(?P<size>[0-9]{1,16})[\s]{1,20}'
'(?P<month>[A-Za-z]{0,3})[\s]{1,20}'
'(?P<date>[0-9]{1,2})[\s]{1,20}'
'(?P<timeyear>[0-9:]{4,5})[\s]{1,20}'
'(?P<filename>[\s\w\.\-]+?)(?=(?:(?:[drwx\-]{10})|$))')
</code></pre>
<p>我在这里所做的(除了使last+变为lazy)是使lookahead检查有两种可能—权限规范或字符串结尾。这个?:是为了防止这些圆括号捕获(否则您将在匹配中得到不需要的额外数据)。你知道吗</p>