0

我在为拉脱维亚公民的个人代码编写正则表达式( php / js )时遇到问题。拉脱维亚的每个公民都有自己的个人密码。格式为 11 位数字,第六位数字后有破折号。所以前6位数字是出生日期。

ddmmyy (例如: 130589 )然后进入破折号( - )然后进入第七位,可以是 0、1 或 2 表示世纪(0 代表 19.世纪和 2 代表 21.世纪),然后数字从 0000 到9999

例子:

080189-12602

08   - day
01   - month
89   - year
-    - dash
1    - 20th century
2602 - random 4 digit combination.

所以问题是有人可以帮我写正则表达式吗?

4

4 回答 4

3

我建议您不要使用正则表达式验证日期。而是只检查正确的格式:

/^(\d{6})-[012]\d{4}$/

这匹配 6 个任意数字,一个破折号,然后是一个来自0to的数字2,然后是 4 个任意数字。之后,您将在捕获组号中找到日期部分1,您可以检查该日期是否有效。或者,您可以分别提取天、月、年:

/^(\d{2})(\d{2})(\d{2})-[012]\d{4}$/

现在日子在抓1,月在抓2,年在抓3。日期范围的验证理论上可以使用正则表达式完成,但实际上不推荐(正则表达式变得非常臃肿且无法维护)。这就是为什么您应该只检查是否有数字,然后您可以使用您的编程语言(PHP 或 JS)来检查给定的数字是否构成有效日期。

于 2012-11-30T19:01:42.093 回答
1
^(0[1-9]|[12][0-9]|3[01])(0[1-9]|1[012])(\d{2})-(0|1|2)(\d{4})$
  • ^- 字符串的开头
  • (0[1-9]|[12][0-9]|3[01])01-09、10-29、30 或 31(天)
  • (0[1-9]|1[012])01-09、10、11 或 12(月)
  • (\d{2})任意两位数(年份)
  • -破折号
  • (0|1|2)0、1 或 2(世纪数字)
  • (\d{4})任意四位数

http://regexr.com?330dj

请注意,这不会处理某些无效日期的情况,例如 2 月 31 日等。这基本上不可能仅使用正则表达式。

于 2012-11-30T19:05:41.563 回答
0
^[0-3][0-9][01][0-9][0-9][0-9]-[012][0-9][0-9][0-9][0-9]$

一个月中的某天(最多 39 天);一年中的月份(最多 19 个);00 至 99 年;世纪和 4 位数字。

这是一个非常通用的正则表达式。还有很多其他的写法。其中一些可能更清晰,一些可能更快。您可以使用以下符号使范围更精确:

([012][0-9]|3[01])

它只接受一个月中的 31 的值。但是,您仍然需要拒绝 2 月 31 日,这不是您想尝试在正则表达式中编码的事情(毫无疑问,可以这样做;您只是不想尝试)。

于 2012-11-30T19:00:55.377 回答
0

它不是正则表达式,也不是最漂亮的代码,但您可以使用以下代码从 ID 中获取所有位:

<?php
$input = '080189-12602';
$id_arr = explode('-', $input);
list($day, $month, $year) = str_split($id_arr[0], 2);

$arr = str_split($id_arr[1]);
$century = 18 + $arr[0];
$id = implode('', array_slice($arr, -4));

printf("%s -> %s%s/%s/%s-%s", $input, $century, $year, $month, $day, $id);
//output: 080189-12602 -> 1989/01/08-2602

鉴于日期的古怪,尝试使用正则表达式验证它们可能是不可取的。例如:试着写一篇告诉你 2 月 29 日是否是有效日期的文章。最好将您的输入切碎并通过一些已实施所有检查的日期库运行它。

于 2012-11-30T19:09:46.977 回答