我是python的新手,对于此作业,我们被要求使用单个正则表达式来解决每个提示。我已经完成了提示A-C,但是现在我被提示D困住了。 这是提示:
d。使用正则表达式进行的替换将日期格式从“ 2019年5月29日”或“ 2019年5月29日”转换为“ 29 May 19”。要匹配的有效日期格式包含以下元素:
•月份必须是常见的三个字母的月份缩写,以大写字母开头,后跟两个小写字母:1月,2月,3月,4月,5月,6月,7月,8月,9月,10月,11月,12月。
•日期可能是一两位数字。不必检查有效的日期,可以接受带有前导零的日期,例如03。
•年份正好是四位数。
•月份和日期由一个或多个空格分隔。日期和年份也用一个或多个空格分隔,但允许在日期之后立即使用逗号(日期和逗号之间不允许有空格)
我遇到的困难:我不确定在r“ ...”语句中输入什么(请参阅代码),现在我得到的错误是“ re.error:逃逸错误\ w位于位置0“,如果我们可以纠正错误或在维持substr = r” ...“的同时找到另一种解决方法,我将非常感激!谢谢!
注意: -我的re.compile代码工作正常,在弄乱子字符串以更改输出之前,它接受了这种情况。它只是没有转换它,因为我还没有编写转换字符串。 -目前即时消息处理的日期还不是很常规,我计划在得到一些可行的方法后再进行处理。
代码:
import re
d = re.compile(r"^((Jan)\s+[1-31],\s+\d{4})$|"
r"^((Jan)\s+[1-31]\s+\d{4})$|"
r"^((Feb)\s+[1-28],\s+\d{4})$|"
r"^((Feb)\s+[1-28]\s+\d{4})$|"
r"^((Feb)\s+[1-29],\s+\d{4})$|" #ask prof about leap years
r"^((Feb)\s+[1-29]\s+\d{4})$|" #ask prof about leap years
r"^((Mar)\s+[1-31],\s+\d{4})$|"
r"^((Mar)\s+[1-31]\s+\d{4})$|"
r"^((Apr)\s+[1-30],\s+\d{4})$|"
r"^((Apr)\s+[1-30]\s+\d{4})$|"
r"^((May)\s+[1-31],\s+\d{4})$|"
r"^((May)\s+[1-31]\s+\d{4})$|"
r"^((Jun)\s+[1-30],\s+\d{4})$|"
r"^((Jun)\s+[1-30]\s+\d{4})$|"
r"^((Jul)\s+[1-31],\s+\d{4})$|"
r"^((Jul)\s+[1-31]\s+\d{4})$|"
r"^((Aug)\s+[1-31],\s+\d{4})$|"
r"^((Aug)\s+[1-31]\s+\d{4})$|"
r"^((Sep)\s+[1-30],\s+\d{4})$|"
r"^((Sep)\s+[1-30]\s+\d{4})$|"
r"^((Oct)\s+[1-31],\s+\d{4})$|"
r"^((Oct)\s+[1-31]\s+\d{4})$|"
r"^((Nov)\s+[1-30],\s+\d{4})$|"
r"^((Nov)\s+[1-30]\s+\d{4})$|"
r"^((Dec)\s+[1-31],\s+\d{4})$|"
r"^((Dec)\s+[1-31]\s+\d{4})$")
subStr = r"\w\s\d{1,2}\s\d{4}"
print("----Part d tests that match (and should change):")
print(d.sub(subStr, "May 29, 2019"))
print("----Part d tests that match (and should remain unchanged):")
print(d.sub(subStr, "May 29 19"))
预期输出:
----Part d tests that match (and should change):
May 29 19
----Part d tests that match (and should remain unchanged):
May 29 19
实际输出(如果我将子字符串留空,以及当前情况如何):
Blank:
----Part d tests that match (and should change):
May 29, 2019
----Part d tests that match (and should remain unchanged):
May 29 19
--------------------------------
Current:
----Part d tests that match (and should change):
this = chr(ESCAPES[this][1])
KeyError: '\\w'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:/Users/Xavier/PycharmProjects/hw7/hw7.py", line 101, in <module>
print(d.sub(subStr, "May 29, 2019"))
File "C:\Users\Xavier\AppData\Local\Programs\Python\Python37\lib\re.py", line 309, in _subx
template = _compile_repl(template, pattern)
File "C:\Users\Xavier\AppData\Local\Programs\Python\Python37\lib\re.py", line 300, in _compile_repl
return sre_parse.parse_template(repl, pattern)
File "C:\Users\Xavier\AppData\Local\Programs\Python\Python37\lib\sre_parse.py", line 1024, in parse_template
raise s.error('bad escape %s' % this, len(this))
re.error: bad escape \w at position 0
答案 0 :(得分:0)
提示:
(Jan|Feb|Mar)
匹配并捕获月份,将其扩展为所有月份。[1-31]
实际上是[123]
...范围1-3或1(冗余)。 [0-9]
或仅\d
匹配任何一位数字。要求说日期不需要验证,因此\d{1,2}
(匹配1或两位数字)应合法。?
用于0或1匹配,因此,?
是可选的逗号。\d{2}(\d{2})
。\n
,其中n
是组号会插入捕获的内容,因此替换只是r'\2 \1 \3'
。答案 1 :(得分:0)
如果不是必须使用正则表达式,我会改用pandas.to_datetime
或time.strptime
:
import pandas as pd
s = "Jun 29, 2019"
try:
print(pd.to_datetime(s).strftime('%d %b %Y'))
except ValueError:
print('unrecognized time format!')
%b
表示月份的缩写,有关完整列表,请参见the docs。
或者如果您没有安装熊猫,请使用内置库time
:
import time
out = None
for pattern in ['%b %d, %Y', '%b %d %Y']:
try:
out = time.strftime('%d %b %Y', time.strptime(s, pattern))
except ValueError:
continue
if out is None:
print('Error: Could not read the time')
如果您必须为此使用正则表达式,则需要替换[1-31]
与(?:[12]\d|3[01]|\d)
,请参阅regex tester。
,然后您错误地使用了re.sub
。您可能想在第一个大正则表达式中插入捕获组,然后在替换字符串中使用\1, \2, ...
来将它们放回去,所以没有\w
我能想到的使用正则表达式并检查日期的唯一方法是
(?:(Jan|Mar|May|Jul|Aug|Oct|Dec) (3[01]|[12]\d|\d)|(Apr|Jun|Sep|Nov) (30|[12]\d|\d)|(Feb) (2[0-9]|[1]\d|\d)),? (\d{4})
并使用
subStr = '\1\3\5 \2\4\6 \7'
这太丑陋了,不治疗treat年。