正则表达式匹配以测试有效年份


89

给定一个值,我想验证它是否是有效的年份。我的标准很简单,其中值应为带4字符的整数。我知道这不是最好的解决方案,因为它不会允许几年以前的时间,1000而且会允许诸如此类的时间5000。这个标准足以满足我目前的情况。

我想出的是

\d{4}$

尽管这可行,但它也允许负值。

如何确保只允许使用正整数?


首先,我创建了一个node.js项目,将其设置为Regex-range以自动创建这些范围。如果您需要生成正则表达式来进行数年的测试,这比看起来要难。
jonschlinkert

为什么将验证时间限制为4位数年?longnow.org
丹·

Answers:


76

您需要添加起始锚^为:

^\d{4}$

您的正则表达式\d{4}$将匹配以4位数字结尾的字符串。因此,类似的输入-1234将被接受。

通过添加起始​​锚,您只能匹配以4位数字开头和结尾的字符串,这实际上意味着它们必须仅包含4位数字。


2
该死的!我的缺陷如此严重,以至于甚至无法接受whateverblahblah2323。现在,我明白了为什么学习有些危险:O
Ranhiru Jude Cooray 2010年

61
这将在10,000年内打破。
sferik 2012年

16
@sferik:没关系。原始海报明确表示他想检查四个字符。他没有声明他希望将10,000年作为有效输入,因此接受10000将是一个错误。
markusk

4
@sferik:到那时该程序将消失几个世纪。如果没有,那么最好担心将来的9000年。遵循YAGNI的原理,该方法是有效的。
菲尔(Phil)

179

从1000年到2999年

^[12][0-9]{3}$

1900-2099年

^(19|20)\d{2}$

14
这是一个更好的解决方案
mk_89

10
我最好使用非捕获组:^(?:19|20)\d{2}$
Eldar Agalarov

如何验证2011年至2099年之间的4位数年份?
mcquaim '17

我如何添加(19|20)\d{2}我的正则表达式以验证生日格式?这是我的正则表达式,/^[0-9]{1,2}\/(0[1-9])|(1[0-2])\/[0-9]{4}$/我要确保该年份始终为4位数字,并以19 **或20 **开头
ltdev

在1900年-2999年内使用^(19 | 2 [0-9])\ d {2} $
MarcoZen '18年

22

该问题的“可接受”答案既不正确又近视。

这是不正确的,因为它将匹配诸如的字符串0001,这不是有效的年份。

这是近视的,因为它将匹配任何高于9999的值。我们是否已经忘记了Y2K的课程?而是使用正则表达式:

^[1-9]\d{3,}$

如果您需要匹配过去的年份,以及未来的年份,则可以使用此正则表达式匹配任何正整数:

^[1-9]\d*$

即使您不希望看到过去的日期,也可能仍要使用此正则表达式,以防万一有人发明了一种时光机并希望将您的软件带回去。

注意:此正则表达式将匹配所有年份,包括第一年之前的年份,因为它们通常用BC名称而不是负整数表示。当然,此约定可能在接下来的几千年中发生变化,因此,最佳选择是使用以下正则表达式匹配任何整数(正数或负数):

^-?[1-9]\d*$

3
不,可能不会。但是,某人(考古学家或历史学家?)可能需要匹配8000年前的年份。:D和Doc Brown可能需要它...
Jaime 2014年

1
我用它来限制范围1000-9999 ^ [1-9] \\ d {3} $那是因为我们必须提供数据的应用程序只接受4位数字:(
MatPag

很棒的答案。我也将使其也接受0年:^(-?[1-9] \ d * | 0)$
Kosta Kontos


5

基于1970-2019年的@ r92答案:

(19[789]\d|20[01]\d)

您的答案允许197999
avalanche1 2013年

我不认为它...正则表达式的第一部分匹配以19开头的数字,然后是7,8或9中的任何一个,然后是单个数字。正则表达式19[789]\d\d\d将允许197999
Renaud

1
/(19[789]\d|20[01]\d)/.test(1970324) >> true
avalanche1

是的,它将匹配前4个数字(1970),而不是最后3个数字(19[789]\d|20[01]\d)[^0-9]。那会匹配,1970 324但不会匹配1970324
Renaud

1
我发现这一点对于从文件名中查找电影年份很有用...在这种情况下,我们需要从1930年代开始的内容...但是我们排除了为视频质量而添加的1024
Adrian Hum

2

理论上,4位数选项是正确的。但实际上,最好具有1900-2099的射程。

另外,它必须是非捕获组。许多评论和答案建议捕获不正确的恕我直言的分组。因为它可能匹配,但是为了使用正则表达式提取匹配项,由于括号的原因,它将提取4位数字和两位数字(19和20)。

这将适用于使用非捕获组的精确匹配:

(?:19|20)\d{2}


1

你可以像[某事去^-]\d{4}$:你防止减号-是你的4位前。
您还可以使用^\d{4}$with^来捕获字符串的开头。这实际上取决于您的情况...


1

要在包含其他单词的字符串中测试年份以及年份,可以使用以下正则表达式:\ b \ d {4} \ b


这正是我所需要的,被接受的答案似乎不是有效的PCRE。
普罗米修斯


0

您可以将整数转换为字符串。由于减号与数字不匹配,因此您将没有负数年。


0

我在Java中使用此正则表达式 ^(0[1-9]|1[012])[/](0[1-9]|[12][0-9]|3[01])[/](19|[2-9][0-9])[0-9]{2}$

从1900到9999的作品


0

/ ^ \ d {4} $ / 这将检查字符串是否仅包含4个数字。在这种情况下,要输入年份989,可以改用0989。


0

如果您需要匹配YYYY或YYYYMMDD,则可以使用:

^((?:(?:(?:(?:(?:[1-9]\d)(?:0[48]|[2468][048]|[13579][26])|(?:(?:[2468][048]|[13579][26])00))(?:0?2(?:29)))|(?:(?:[1-9]\d{3})(?:(?:(?:0?[13578]|1[02])(?:31))|(?:(?:0?[13-9]|1[0-2])(?:29|30))|(?:(?:0?[1-9])|(?:1[0-2]))(?:0?[1-9]|1\d|2[0-8])))))|(?:19|20)\d{2})$

0

您也可以使用这个。

([0-2][0-9]|3[0-1])\/([0-1][0-2])\/(19[789]\d|20[01]\d)

他们只想匹配年份。此外,您的正则表达式匹配00/00/200031/02/1999还有更多错误的日期。
Toto

可能会帮助您[[0-2] [0-9] | 3 [0-1])\ /([0-1] [0-2])\ /(19 [789] \ d | 20 [01 ] \ d)
Ranjeet Chouhan,

(0[1-9]|1[0-2])对于一个月一个更好的表达
EZ-C
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.