Python 如何根据每个元素中的子字符串筛选列表?

Python 如何根据每个元素中的子字符串筛选列表?,python,Python,我有一个不一致的字符串列表,其中包含不同格式的日期。我需要确定每个列表中的日期 我的列表/数组如下所示: dates\u list=[] my_数组=[ “5364345354_01.05.2019.pdf”, “5364344354_01.05.2019.pdf”, “53453454-21.06.2019.pdf”, “4675535643-2019年6月19日,docx”, “57467874 25.06.18.pdf”, “653635_2019年3月20日.txt”, “252452_

我有一个不一致的字符串列表,其中包含不同格式的日期。我需要确定每个列表中的日期

我的列表/数组如下所示:

dates\u list=[]
my_数组=[
“5364345354_01.05.2019.pdf”,
“5364344354_01.05.2019.pdf”,
“53453454-21.06.2019.pdf”,
“4675535643-2019年6月19日,docx”,
“57467874 25.06.18.pdf”,
“653635_2019年3月20日.txt”,
“252452_31.1.2019.txt”
]

我尝试了for循环并尝试拆分字符串,但是每个字符串在日期之前都有不同的分隔符。那么,从这个不一致的列表中的每个字符串中找到日期的可行方法是什么呢。查看列表的唯一帮助是日期都位于每个字符串的末尾。这不是最好的方法,但它可能会解决您的问题,您可以对其进行更多调整:

dates_list = []
my_array = [
'5364345354_01.05.2019.pdf',
'5364344354_ 01.05.2019.pdf',
'5345453454 - 21.06.2019.pdf',
'4675535643 - 19 June 2019.docx',
'57467874 25.06.18.pdf',
'6565653635_20 March 2019.txt',
'252252452_31.1.2019.txt'
]

import os 

for i in my_array : 
  for j in i : 
    if j >= '0' and j <= '9' : 
      i = i.replace(j,"",1)
    else:
      break 
  print(os.path.splitext(i)[0].replace("_","").replace("-",""))

这可以用正则表达式解决。我在这里使用的模式在这种情况下是有效的,但它并不漂亮

import re

regex = re.compile(r'\d{1,2}(\.| )\w+\1\d{2,4}')

for f in my_array:
    print(regex.search(f).group())
输出:

2019年5月1日
01.05.2019
21.06.2019
2019年6月19日
25.06.18
2019年3月20日
31.1.2019
细分:

  • \d{1,2}
    -一位或两位数字
  • (\.|)
    <代码>\1-一个点或一个空格,然后再重复相同的内容
  • \w+
    -一个或多个字母、数字或下划线
  • \d{2,4}
    -两位或四位数字

现在还不清楚您想对日期做什么,或者是否希望它们采用某种一致的格式,但是您的问题是您想从文件名中提取日期。您可以根据示例使用regex实现这一点,您说这是您仅有的7种格式

my_array = [
'5364345354_01.05.2019.pdf',
'5364344354_ 01.05.2019.pdf',
'5345453454 - 21.06.2019.pdf',
'4675535643 - 19 June 2019.docx',
'57467874 25.06.18.pdf',
'6565653635_20 March 2019.txt',
'252252452_31.1.2019.txt'
]

import re
for filename in my_array:
    date = re.search(r'(\d{1,2}([.\s])(?:\d{1,2}|\w+)\2\d{2,4})', filename).group()
    print(f"The date '{date}' was extracted from the file name '{filename}'")
输出

The date '01.05.2019' was extracted from the file name '5364345354_01.05.2019.pdf'
The date '01.05.2019' was extracted from the file name '5364344354_ 01.05.2019.pdf'
The date '21.06.2019' was extracted from the file name '5345453454 - 21.06.2019.pdf'
The date '19 June 2019' was extracted from the file name '4675535643 - 19 June 2019.docx'
The date '25.06.18' was extracted from the file name '57467874 25.06.18.pdf'
The date '20 March 2019' was extracted from the file name '6565653635_20 March 2019.txt'
The date '31.1.2019' was extracted from the file name '252252452_31.1.2019.txt'

你可以试试这个,有点老套,但你的约会格式确实有一些变化:)

输出:

['01-05-2019', '01-05-2019', '21-06-2019', '19June2019', '25-06-18', '20March2019', '31-1-2019']

for i,d in enumerate(unformatted):
    if any(c.isalpha() for c in d):
        key = re.search('[a-zA-Z]+',d).group()
        unformatted[i] = d.replace(key,'-'+mons[key]+'-')
    if len(d.split('-')[-1])==2:
        yr = d.split('-')[-1]
        unformatted[i] = d[:-2]+'20'+yr

#was having issues getting this one to work in the same loop..but:
for i,d in enumerate(unformatted):
    if len(d.split('-')[1])==1:
        mnth = d.split('-')[1]
        unformatted[i] = d[:3]+'0'+mnth+d[-5:]
输出:

['01-05-2019', '01-05-2019', '21-06-2019', '19-06-2019', '25-06-2018', '20-03-2019', '31-01-2019']
这不仅可以提取每个条目的日期,还可以将它们转换为相同的格式,以便您可以在pandas中使用它们,或者以后需要对它们执行的任何操作

如果提供的示例包含日期的所有变体,则应该可以使用,如果没有,您可以进行一些较小的调整,并且应该能够使其工作

该模块在处理日期和日期格式时非常有用,可能有助于将各种格式的日期转换为单一格式

额外的字符,如日期前的数字,仍然需要手动删除。其他答案已经指出了几种方法,这里我提出了我自己的方法,不需要正则表达式。我将假设这些模式就是您的示例中所示的模式,如果有其他模式需要包含在代码中

一旦字符串开头的数字和文件扩展名被丢弃,就会使用
datetime.strtime()
读取日期并创建
datetime
对象。
然后使用
datetime.strftime()
返回一个字符串,该字符串表示具有给定唯一格式的日期

import datetime

my_array = [
'5364345354_01.05.2019.pdf',
'5364344354_ 01.05.2019.pdf',
'5345453454 - 21.06.2019.pdf',
'4675535643 - 19 June 2019.docx',
'57467874 25.06.18.pdf',
'6565653635_20 March 2019.txt',
'252252452_31.1.2019.txt'
]

def multiformat(string, format_list, format_res):
    delim = None
    if '_' in string:
        delim = '_'
    elif '-' in string:
        delim = '-'
    else:
        delim = ' '

    strdate = string.split(delim)[1].strip().split('.')[:-1]
    txtdate = ' '.join(strdate)

    print(txtdate)
    date = None
    for frm in format_list:
        try:
            date = datetime.datetime.strptime(txtdate, frm)
            break
        except ValueError:
            pass

    return date.strftime(format_res)

format_dates = ['%d %m %Y', '%d %m %y', '%d %B %Y']
dates_list = list(map(lambda x : multiformat(x, format_dates, '%d-%m-%Y'), my_array))
print(dates_list)
这张照片是:

['01-05-2019', '01-05-2019', '21-06-2019', '19-06-2019', '25-06-2018', '20-03-2019', '31-01-2019']

这些都是您必须解析的字符串的可能变体吗?是的,我已经检查了我的列表,并将其过滤到这些变体7@MisterMiyagi
25.06.18
是2018年6月25日,对吗?尝试使用
regex
Yes@wjandrea。它能与“039383930 01_04_19”这样的字符串一起工作吗?
import datetime

my_array = [
'5364345354_01.05.2019.pdf',
'5364344354_ 01.05.2019.pdf',
'5345453454 - 21.06.2019.pdf',
'4675535643 - 19 June 2019.docx',
'57467874 25.06.18.pdf',
'6565653635_20 March 2019.txt',
'252252452_31.1.2019.txt'
]

def multiformat(string, format_list, format_res):
    delim = None
    if '_' in string:
        delim = '_'
    elif '-' in string:
        delim = '-'
    else:
        delim = ' '

    strdate = string.split(delim)[1].strip().split('.')[:-1]
    txtdate = ' '.join(strdate)

    print(txtdate)
    date = None
    for frm in format_list:
        try:
            date = datetime.datetime.strptime(txtdate, frm)
            break
        except ValueError:
            pass

    return date.strftime(format_res)

format_dates = ['%d %m %Y', '%d %m %y', '%d %B %Y']
dates_list = list(map(lambda x : multiformat(x, format_dates, '%d-%m-%Y'), my_array))
print(dates_list)
['01-05-2019', '01-05-2019', '21-06-2019', '19-06-2019', '25-06-2018', '20-03-2019', '31-01-2019']