我有一列具有不同日期类型的列,例如:
2\06\1998
21.11.1998
18-02-2001
03/05/1999
20 july 1999
我只想要年份。
我尝试了其他类型的正则表达式,例如:
def get_date(date):
number= re.findall('\[0-9]\-{0,1}\\{0,1}\/{0,1}\[0-9]\-{0,1}\\{0,1}\/{0,1}\[0-9]', date)
return number[6:]
但是我无法提取年份。 什么是最适合这种情况的正则表达式? 进行两种类型的正则表达式不是问题,一种用于dd / mm / yyyy格式,一种用于带字母月份的日期。
答案 0 :(得分:2)
不要掉入正则表达式/“最后4个字符的兔子洞”中。
如果到达另一种格式的日期(例如2019-08-27
),则任何幼稚的正则表达式/剥离解决方案都会中断。
使用pd.to_datetime
让熊猫处理解析,然后抓住dt.year
。
df = pd.DataFrame({'a': ['2/06/1998', '21.11.1998', '18-02-2001', '03/05/1999',
'20 july 1999', '2019-08-27']})
df['a'] = pd.to_datetime(df['a'])
print(df['a'].dt.year)
输出
0 1998
1 1998
2 2001
3 1999
4 1999
5 2019
注意:请注意,我必须将斜线的方向(从2\06\1998
更改为2/06/1998
),但是要获得更强大的解决方案却要付出很小的代价。
答案 1 :(得分:0)
您可以利用2个捕获组,其中在第一个组中,通过使用向后引用\1
来捕获分隔线以匹配第二个分隔线的一致分隔线。
年份部分在第二组中捕获。
^\d+([\\/. -])(?:\d+|[a-z]+)\1(\d{4})$
除了使用锚点^
和$
,您还可以使用lookarounds
(?<!\S)\d+([\\/. -])(?:\d+|[a-z]+)\1(\d{4})(?!\S)
样式部分
(?<!\S)
声明左侧的内容不是非空白字符\d+
匹配1个以上的数字([\\/. -])
捕获组1,与列出的任何一个匹配(?:
非捕获组
\d+
匹配1个以上的数字|
或[a-z]+
匹配1个以上的小写字符)
关闭无标题组\1
向后引用第1组中捕获的内容(\d{4})
捕获组2,匹配年份的4位数字(?!\S)
断言右边的内容不是非空格字符答案 2 :(得分:0)
我将使用简单的\d{4}
正则表达式。
import re
s = """2\\06\\1998
21.11.1998
18-02-2001
03/05/1999
20 july 1999"""
for date in s.splitlines():
year = re.search(r"\d{4}", date).group(0)
print(year)
答案 3 :(得分:0)
熊猫to_datetime擅长识别不同的日期格式。唯一的问题是反斜杠,但是如果您可以使用字符串格式替换反斜杠,那么我认为它比使用正则表达式更容易。
import pandas as pd
df = pd.DataFrame({"date": ["2\\06\\1998", "21.11.1998", "18-02-2001", "03/05/1999", "20 july 1999"]})
df["date"] = df["date"].str.replace("\\", "/")
df["date"] = pd.to_datetime(df["date"])
df["date"].dt.year
0 1998
1 1998
2 2001
3 1999
4 1999
Name: date, dtype: int64