我在下面的正则表达式匹配
中做错了什么>>> import re
>>> d="30-12-2001"
>>> re.findall(r"\b[1-31][/-:][1-12][/-:][1981-2011]\b",d)
[]
答案 0 :(得分:6)
[1-31]
匹配1-3
和1
,基本上是1,2或3.除非它是0-9的子集,否则无法匹配数字愤怒。同样适用于[1981-2011]
,它恰好匹配一个0,1,2,8或9的字符。
最好的解决方案是简单地匹配任何号码,然后使用python本身检查数字。诸如31-02-2012
之类的日期没有任何意义 - 并且使您的正则表达式检查很难。使它也适当地处理闰年将使它更难或不可能。这是一个正则表达式匹配任何看起来像dd-mm-yyyy
日期的内容:\b\d{1,2}[-/:]\d{1,2}[-/:]\d{4}\b
但是,我强烈建议不允许任何-
,:
和/
作为:
通常用于/
通常用于美国为ISO方式(mm/dd/yyyy
)编写日期(-
)和yyyy-mm-dd
的方式。欧盟dd.mm.yyyy
语法根本没有处理。
如果字符串除日期外不包含任何内容,则根本不需要正则表达式 - 请改用strptime()
。
总而言之,告诉用户您期望的日期格式并解析该日期格式,拒绝其他任何内容。否则你会得到含糊不清的案例,例如04/05/2012
(是5月5日还是4月?)。
答案 1 :(得分:1)
[1-31]
并不代表您认为的含义。方括号语法匹配一系列字符,而不是一系列数字。可以使用正则表达式匹配一系列数字,但不实用。
如果您真的想为此使用正则表达式(而不是日期解析库),最好匹配正确数字位数的所有数字,捕获值,然后自己检查值:
>>> import re
>>> d="30-12-2001"
>>> >>> re.findall(r"\b([0-9]{1,2})[-/:]([0-9]{1,2})[-/:]([0-9]{4})\b",d)
[('30', '12', '2001')]
无论如何,您必须进行实际日期验证,以捕获31-02-2012
之类的无效日期。
(注意[/-:]
也不起作用,因为它被解释为一个范围。使用[-/:]
代替 - 将连字符放在前面可防止它被解释为范围分隔符。)
答案 2 :(得分:1)
正则表达式不理解数字;对于正则表达式,1
只是字符串的一个字符 - 与a
相同。因此,例如,[1-31]
被解析为包含范围1-3
和(冗余)单个符号1
的字符类。
您不希望使用正则表达式来解析日期。已有一个用于处理日期解析的内置模块:
>>> import datetime
>>> datetime.datetime.strptime('30-12-2001', '%d-%m-%Y')
datetime.datetime(2001, 12, 30, 0, 0) # an object representing the date.
这也会为您完成所有二次检查(例如尝试参考2月31日)。如果你想处理多种类型的分隔符,你只需在原始字符串中.replace
它们,这样它们就会变成同一个分隔符,然后以你的格式使用它。
答案 3 :(得分:1)
你可能做错了。这里的一些其他回复正在帮助您使用正则表达式,但我建议您使用datetime.strptime
方法将格式化日期转换为日期时间对象,并使用该对象执行进一步的逻辑:
>>> import datetime
>>> datetime.strptime('30-12-2001', '%d-%m-%Y')
datetime.datetime(2001, 12, 30, 0, 0)
答案 4 :(得分:1)
regexp = r'(0?[1-9] | [12] [0-9] | 3 [01])/(0?[1-9] | 1 [012])/((19 | 20)\ d \ d)'
( #start of group #1 0?[1-9] # 01-09 or 1-9 | # ..or [12][0-9] # 10-19 or 20-29 | # ..or 3[01] # 30, 31 ) #end of group #1 / # follow by a "/" ( # start of group #2 0?[1-9] # 01-09 or 1-9 | # ..or 1[012] # 10,11,12 ) # end of group #2 / # follow by a "/" ( # start of group #3 (19|20)\\d\\d # 19[0-9][0-9] or 20[0-9][0-9] ) # end of group #3
答案 5 :(得分:0)
也许你可以试试这个正则表达式
^((0|1|2)[0-9]{1}|(3)[0-1]{1})/((0)[0-9]{1}|(1)[0-2]{1})/((19)[0-9]{2}|(20)[0-9]{2})$
此匹配为(01至31)/(01至12)/(1900至2099)