Python正则表达式前瞻超调模式

2024-06-16 11:44:53 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试提取FTP列表中包含的数据。你知道吗

我在python2.7中使用regex。你知道吗

test = "-rw-r--r--   1 owner    group        75148624 Jan  6  2015 somename.csv-rw-r--r--   1 owner    group       223259072 Feb 26  2015 somename.csv-rw-r--r--   1 owner    group         4041411 Jun  5  2015 somename-adjusted.csv-rw-r--r--   1 owner    group         2879228 May 13  2015 somename.csv-rw-r--r--   1 owner    group        11832668 Feb 13  2015 somename.csv-rw-r--r--   1 owner    group         1510522 Feb 19  2015 somename.csv-rw-r--r--   1 owner    group         2826664 Feb 25  2015 somename.csv-rw-r--r--   1 owner    group          582985 Feb 26  2015 somename.csv-rw-r--r--   1 owner    group          212427 Feb 26  2015 somename.csv-rw-r--r--   1 owner    group         3015592 Feb 27  2015 somename.csv-rw-r--r--   1 owner    group          103576 Feb 27  2015    somename-corrected.csv"

(现在没有代码格式,因此您可以看到它而无需滚动)

test=“-rw-r--r--1所有者组75148624 2015年1月6日somename.csv文件-rw-r--r--1业主组223259072 2015年2月26日somename.csv文件-rw-r--r--1业主组4041411 2015年6月5日somename-调整后.csv-rw-r--r--1业主组2879228 2015年5月13日somename.csv文件-rw-r--r--1所有者组11832668 2015年2月13日somename.csv文件-rw-r--r--1业主组1510522 2015年2月19日somename.csv文件-rw-r--r--1业主组2826664 2015年2月25日somename.csv文件-rw-r--r--1业主组582985 2015年2月26日somename.csv文件-rw-r--r--1业主组212427 2015年2月26日somename.csv文件-rw-r--r--1所有者组3015592 2015年2月27日somename.csv文件-rw-r--r--1业主组103576 2015年2月27日somename-更正.csv““

我试过以下的各种化身

from re import compile
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})')

最后一行是

'(?P<filename>.+)(?=[drwx\-]{10})')

'(?P<filename>.+(?=[drwx\-]{10}))')

最初

'(?P<filename>[\s\w\.\-]+(?=[drwx\-]{10}|$))') 

所以我可以截取最后一个条目

但不管怎样,我一直得到以下输出

ftp_list_re.findall(test)

[('-rw-r--r--',
  '1',
  'owner',
  'group',
  '75148624',
  'Jan',
  '6',
  '2015',
  'somename.csv-rw-r--r--   1 owner    group       223259072 Feb 26  2015     somename.csv-rw-r--r--   1 owner    group         4041411 Jun  5  2015 somename-adjusted.csv-rw-r--r--   1 owner    group         2879228 May 13  2015 somename.csv-rw-r--r--   1 owner    group        11832668 Feb 13  2015 somename.csv-rw-r--r--   1 owner    group         1510522 Feb 19  2015 somename.csv-rw-r--r--   1 owner    group         2826664 Feb 25  2015 somename.csv-rw-r--r--   1 owner    group          582985 Feb 26  2015 somename.csv-rw-r--r--   1 owner    group          212427 Feb 26  2015 somename.csv-rw-r--r--   1 owner    group         3015592 Feb 27  2015 somename.csv')]

我做错什么了?你知道吗


Tags: 文件csvtestregroupfilenamejunjan
3条回答

正则表达式量词在默认情况下是“贪婪的”,这意味着它们将尽可能地“吃”。你知道吗

[\s\w\.\-]+

表示查找至少一个且尽可能多的空格、单词、点或破折号字符。向前看防止它吃掉整个输入(实际上regex引擎会吃掉整个输入,然后根据需要开始后退),这意味着它吃掉每个文件规范行,除了最后一行(向前看坚持必须留下)。你知道吗

添加一个?在量词(*)之后?, +?, ??,等等)使量词“懒惰”或“不情愿”。这将“+”的含义从“匹配至少一个且尽可能多”更改为“匹配至少一个且不超过所需”。你知道吗

所以把最后一个+改成a+?应该能解决你的问题。你知道吗

问题不在于向前看,它工作得很好,而在于它前面的最后一个子表达式。你知道吗

编辑:

即使进行了此更改,正则表达式也不会解析最后一行文件规范。这是因为正则表达式坚持文件名后面必须有权限规范。要解决这个问题,我们必须允许前瞻性不匹配(但要求它在除最后一个规范之外的所有方面都匹配)。进行以下更改将解决此问题

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})|$))')

我在这里所做的(除了使last+变为lazy)是使lookahead检查有两种可能—权限规范或字符串结尾。这个?:是为了防止这些圆括号捕获(否则您将在匹配中得到不需要的额外数据)。你知道吗

你应该在向前看之前创建子模式。此外,您的正则表达式可以缩短如下:

(?P<permissions>[d-][rwx-]{9})\s{1,20}(?P<links>\d{1,8})\s{1,20}(?P<owner>[\w-]{1,16})\s{1,20}(?P<group>[\w-]{1,16})\s{1,20}(?P<size>\d{1,16})\s{1,20}(?P<month>[A-Za-z]{0,3})\s{1,20}(?P<date>\d{1,2})\s{1,20}(?P<timeyear>[\d:]{4,5})\s{1,20}(?P<filename>[\s\w.-]+?)(?=[drwx-]{10}|$)

或使用compile

from re import compile

ftp_list_re = compile('(?P<permissions>[d-][rwx-]{9})\s{1,20}'
   '(?P<links>\d{1,8})\s{1,20}'
   '(?P<owner>[\w-]{1,16})\s{1,20}'
   '(?P<group>[\w-]{1,16})\s{1,20}'
   '(?P<size>\d{1,16})\s{1,20}'
   '(?P<month>[A-Za-z]{0,3})\s{1,20}'
   '(?P<date>\d{1,2})\s{1,20}'
   '(?P<timeyear>[\d:]{4,5})\s{1,20}'
   '(?P<filename>[\s\w.-]+?)(?=[drwx-]{10}|$)')

RegEx Demo

代码:

import re
p = re.compile(ur'(?P<permissions>[d-][rwx-]{9})\s{1,20}(?P<links>\d{1,8})\s{1,20}(?P<owner>[\w-]{1,16})\s{1,20}(?P<group>[\w-]{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>[\d:]{4,5})\s{1,20}(?P<filename>[\s\w.-]+?)(?=[drwx-]{10}|$)')
test_str = u"-rw-r--r--   1 owner    group        75148624 Jan  6  2015 somename.csv-rw-r--r--   1 owner    group       223259072 Feb 26  2015 somename.csv-rw-r--r--   1 owner    group         4041411 Jun  5  2015 somename-adjusted.csv-rw-r--r--   1 owner    group         2879228 May 13  2015 somename.csv-rw-r--r--   1 owner    group        11832668 Feb 13  2015 somename.csv-rw-r--r--   1 owner    group         1510522 Feb 19  2015 somename.csv-rw-r--r--   1 owner    group         2826664 Feb 25  2015 somename.csv-rw-r--r--   1 owner    group          582985 Feb 26  2015 somename.csv-rw-r--r--   1 owner    group          212427 Feb 26  2015 somename.csv-rw-r--r--   1 owner    group         3015592 Feb 27  2015 somename.csv-rw-r--r--   1 owner    group          103576 Feb 27  2015 somename-corrected.csv"

re.findall(p, test_str)

修复了你的最后一行,文件名组不工作。请参见下面的fixed regex和演示:

(?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>[\w\-]+.\w+)

演示here:

相关问题 更多 >