Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/355.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何将与正则表达式匹配的所有字符串放入Python中的列表中?_Python_Regex_List_Date - Fatal编程技术网

如何将与正则表达式匹配的所有字符串放入Python中的列表中?

如何将与正则表达式匹配的所有字符串放入Python中的列表中?,python,regex,list,date,Python,Regex,List,Date,因此,在我的Python脚本中,我打开了一个文本文件,其中包含格式为“1991年1月26日”的日期 这是我的正则表达式: pattern = """ (?:(September|April|June|November),\ (0?[1-9]|[12]\d|30),\ ((?:19|20)\d\d))#Months with 30 days |(?:(January|March|May|July|August|October|December),\ (0?[1-9]|[12]\d|3[01])

因此,在我的Python脚本中,我打开了一个文本文件,其中包含格式为“1991年1月26日”的日期

这是我的正则表达式:

pattern = """
(?:(September|April|June|November),\ (0?[1-9]|[12]\d|30),\ ((?:19|20)\d\d))#Months   with 30 days
|(?:(January|March|May|July|August|October|December),\ (0?[1-9]|[12]\d|3[01]),\ ((?:19|20)\d\d))#Months with 31 days
|(?:February, (?:(?:(0?[1-9]|1\d|2[0-8]),\ ((?:19|20)\d\d))|(?:(29),\ ((?:(?:19|20)(?:04|08|12|16|20|24|28|32|36|40|44|48|52|56|60|64|68|72|76|80|84|88|92|96))|2000))))#February with 28 days or 29 with a leap year
"""

r = re.compile(pattern, re.VERBOSE)
此正则表达式应匹配任何实际日期,包括闰年的2月29日

我遇到的问题是想办法浏览我打开的文本文件,并将所有匹配的日期放入一个列表中。我试过使用.match、.search、.split和其他工具,但我没有任何运气。是否有一种方法可以将所有匹配项作为字符串放入列表中,以便我可以轻松地将列表与另一个列表进行比较,并找到两个列表中的所有日期?基本上我想要一份清单

[“1990年1月1日”、“2012年2月29日”、“1945年12月25日”、…]

另外,请让我知道我的正则表达式是否正确。我根据我的另一个问题的答案修改了它,我不确定是否正确,因为我看不出文本文件中的日期是否匹配。

您在尝试的事情列表中没有提到。这将为您提供所有正则表达式匹配项的列表

但是,您需要使用所有非捕获组
(?:…)
,否则您将获得所有匹配组的列表
(…)
。因此,我建议

pattern = """
    (?:September|April|June|November)
    ,[ ] 
    (?:0?[1-9]|[12]\d|30)
    ,[ ]
    (?:19|20)\d\d # Months with 30 days

    |

    (?:January|March|May|July|August|October|December)
    ,[ ] 
    (?:0?[1-9]|[12]\d|3[01])
    ,[ ] 
    (?:19|20)\d\d # Months with 31 days

    |

    February
    ,[ ] 
    (?:
     (?:0?[1-9]|1\d|2[0-8])
     ,[ ] 
     (?:19|20)\d\d
    |
     29
     ,[ ] 
     (?:
      (?:19|20)
      (?:04|08|12|16|20|24|28|32|36|40|44|48|
         52|56|60|64|68|72|76|80|84|88|92|96)
     |
      2000
     )
    ) # February with 28 days or 29 with a leap year"""
但是你真的需要验证日期的正确性吗?您是否希望数据中出现2000年2月31日之类的错误日期?否则,您可以极大地简化正则表达式。或者至少将日期验证委托给一个日期解析函数,该函数比一个庞大的正则表达式更适合此任务

例如:

pattern = """
    (?:January|February|March|April|May|June|
       July|August|September|October|November|December)
    ,[ ]
    [0-3]?\d
    ,[ ]
    (?:19|20)\d\d
"""
匹配1999年1月0日或2000年2月31日之类的废话,但这真的有关系吗?

您在尝试的事情列表中没有提到。这将为您提供所有正则表达式匹配项的列表

但是,您需要使用所有非捕获组
(?:…)
,否则您将获得所有匹配组的列表
(…)
。因此,我建议

pattern = """
    (?:September|April|June|November)
    ,[ ] 
    (?:0?[1-9]|[12]\d|30)
    ,[ ]
    (?:19|20)\d\d # Months with 30 days

    |

    (?:January|March|May|July|August|October|December)
    ,[ ] 
    (?:0?[1-9]|[12]\d|3[01])
    ,[ ] 
    (?:19|20)\d\d # Months with 31 days

    |

    February
    ,[ ] 
    (?:
     (?:0?[1-9]|1\d|2[0-8])
     ,[ ] 
     (?:19|20)\d\d
    |
     29
     ,[ ] 
     (?:
      (?:19|20)
      (?:04|08|12|16|20|24|28|32|36|40|44|48|
         52|56|60|64|68|72|76|80|84|88|92|96)
     |
      2000
     )
    ) # February with 28 days or 29 with a leap year"""
但是你真的需要验证日期的正确性吗?您是否希望数据中出现2000年2月31日之类的错误日期?否则,您可以极大地简化正则表达式。或者至少将日期验证委托给一个日期解析函数,该函数比一个庞大的正则表达式更适合此任务

例如:

pattern = """
    (?:January|February|March|April|May|June|
       July|August|September|October|November|December)
    ,[ ]
    [0-3]?\d
    ,[ ]
    (?:19|20)\d\d
"""
匹配像1999年1月0日或2000年2月31日之类的废话,但这真的重要吗?

随机沉思:

如果你需要问你的正则表达式是否正确,那就太复杂了

re.VERBOSE的思想是使您的正则表达式清晰易读,而不是附加明显的注释,这些注释在任何情况下都是隐藏的。如果您看到SO水平滚动条,则说明您的废话太长

如果
findall
不存在,您可以编写一个循环,使用
search
查找下一个匹配项,并为
search
pos
参数
匹配对象.end()

def myfindall(regex, strg):
    alist = []
    pos = 0
    while True:
        m = regex.search(strg, pos)
        if not m: break
        alist.append(m.group(0))
        pos = m.end()
    return alist
您确定月份名称后应该有逗号吗?

随机沉思:

如果你需要问你的正则表达式是否正确,那就太复杂了

re.VERBOSE的思想是使您的正则表达式清晰易读,而不是附加明显的注释,这些注释在任何情况下都是隐藏的。如果您看到SO水平滚动条,则说明您的废话太长

如果
findall
不存在,您可以编写一个循环,使用
search
查找下一个匹配项,并为
search
pos
参数
匹配对象.end()

def myfindall(regex, strg):
    alist = []
    pos = 0
    while True:
        m = regex.search(strg, pos)
        if not m: break
        alist.append(m.group(0))
        pos = m.end()
    return alist

您确定月份名称后应该有逗号吗?

您可以使用简单的正则表达式进行预处理,并使用以下函数验证日期:

import re
from datetime import datetime

def extract_date_strings(text):
    return filter(valid_date, re.findall(r"[A-Z][a-z]+, \d\d?, \d{4}", text))

def valid_date(datestr):
    try:
        return datetime.strptime(datestr, "%B, %d, %Y") #note: locale dependent
    except ValueError: 
        return None
您可以使用此代码将结果与测试代码进行比较

实例 输出
您可以使用简单的正则表达式进行预处理,并使用以下函数验证日期:

import re
from datetime import datetime

def extract_date_strings(text):
    return filter(valid_date, re.findall(r"[A-Z][a-z]+, \d\d?, \d{4}", text))

def valid_date(datestr):
    try:
        return datetime.strptime(datestr, "%B, %d, %Y") #note: locale dependent
    except ValueError: 
        return None
您可以使用此代码将结果与测试代码进行比较

实例 输出
我确实使用了findall(),但它不起作用。结果是你对我的表情做的修改起了作用。我从我的另一个问题的答案中得到了“?:”操作符,即使在阅读了它的文档之后,我也不完全确定它做了什么。谢谢你的帮助@伊凡:太好了,但我发现2012年2月29日并没有达到应有的水平。我目前正试图筛选残骸并找到解决方案…@JohnMachin:monastrousregex,如图所示:完成。找到了罪犯(2月之后的空间没有逃脱)。我还删除了一些不必要的组,并添加了一些换行符和缩进,以获得些许的清晰度。尽管如此,我还是不认为日期验证对于正则表达式来说是一项好工作。@Ivan:我真的希望老师/教授们更愿意教他们的学生使用哪种工具来达到哪种目的,而不是仅仅因为他们可以,就让他们做一些半疯狂的事情。有太多可怕的正则表达式,给正则表达式一个坏名声。他们不应该这样。我确实使用了findall(),但它不起作用。结果是你对我的表情做的修改起了作用。我从我的另一个问题的答案中得到了“?:”操作符,即使在阅读了它的文档之后,我也不完全确定它做了什么。谢谢你的帮助@伊凡:太好了,但我发现2012年2月29日并没有达到应有的水平。我目前正试图筛选残骸并找到解决方案…@JohnMachin:monastrousregex,如图所示:完成。找到了罪犯(2月之后的空间没有逃脱)。我还删除了一些不必要的组,并添加了一些换行符和缩进,以获得些许的清晰度。不过,我不认为日期验证对于正则表达式来说是一项好工作。@Ivan:我真希望老师/教授更愿意教他们的学生使用哪种工具