Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/321.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_String_List - Fatal编程技术网

Python 按月份分割字符串作为分隔符

Python 按月份分割字符串作为分隔符,python,regex,string,list,Python,Regex,String,List,我试图接收发送的消息的txt文件,并在每次出现日期时将其拆分为一个列表 例如: 'Aug 5 2020: John Doe: Hello Aug 5 2020 Jane Doe: Hi' 将成为 ['Aug 5 2020: John Doe: Hello', 'Aug 5 2020 Jane Doe: Hi'] 在做了一些研究之后,看起来我需要使用re.split(),但我不确定如何使用它。我试过这个: import re def getFile(file): infile=open

我试图接收发送的消息的txt文件,并在每次出现日期时将其拆分为一个列表

例如:

'Aug 5 2020: John Doe: Hello Aug 5 2020 Jane Doe: Hi'
将成为

['Aug 5 2020: John Doe: Hello', 'Aug 5 2020 Jane Doe: Hi']
在做了一些研究之后,看起来我需要使用re.split(),但我不确定如何使用它。我试过这个:

import re
def getFile(file):
    infile=open(file, 'r')
    content=infile.read()
    return content

def cleanup(file):
    messages = getFile(file)    
    m=messages.replace('\n',' ')
    print(m)
    months=['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov']
    print(re.split('Aug|Sep|Oct|Nov', m))
但它没有给我想要的


我应该如何格式化它,以便它执行我需要它执行的操作?

如果用
“()”
包围正则表达式,它还将捕获要拆分的分隔符(在本例中是月名)

比如说,

>>> s = "Aug 5 2020: John Doe: Hello Aug 5 2020 Jane Doe: Hi"
... pattern = r"\b(Aug)\b"
... xs = re.split(pattern, s)
... xs = [(a + b).rstrip() for a, b in zip(xs[1::2], xs[2::2])]

>>> xs
['Aug 5 2020: John Doe: Hello', 'Aug 5 2020 Jane Doe: Hi']
可以构建适用于所有月份的更通用模式:

>>> months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
...           'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
>>> pattern = fr"\b({'|'.join(months)})\b"

>>> pattern
r'\b(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\b'
正如@smci所建议的,可以通过以下方式形成更严格的正则表达式:

>>> pattern = fr"(\b(?:{'|'.join(months)}) \d{{1,2}} \d{{4}}\b)"

>>> pattern
r'(\b(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) \d{1,2} \d{4}\b)'

这迫使我们需要一个月后的一天和一年
“(?:月)”
表示非捕获组,以便
re.split
不会拾取冗余子字符串。

您也可以尝试此
re.split

>>> import re
>>> months=['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec']
>>> s = 'Aug 5 2020: John Doe: Hello Aug 5 2020 Jane Doe: Hi'
>>> rx = re.compile( fr"\s+(?=(?:{'|'.join(months)})\b)", re.I )
>>> print (rx)
re.compile('\\s+(?=(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\\b)', re.IGNORECASE)
>>>
>>> print (rx.split(s))
['Aug 5 2020: John Doe: Hello', 'Aug 5 2020 Jane Doe: Hi']

正则表达式详细信息:

  • \s+
    :匹配1+个空格以断言下一个先行条件
  • (?=
    :开始先行条件
    • (?:一月|二月|三月|四月|五月|六月|七月|八月|九月|十月|十一月|十二月)\\b
      :匹配三个字母的月份名称,后跟单词边界
  • :结束前瞻
  • re.I
    :启用忽略大小写匹配

您可能希望收紧正则表达式以排除“军事”或“八角形”等误报。在您的例子中,您知道3个字母的月份缩写后面跟着空格,然后是1+位,然后是空格,然后是4位YYYY。您可以使用前瞻断言来实现这一点。