我在为拉脱维亚公民个人代码编写正则表达式(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.
所以问题是有人可以帮我写正则表达式吗?
答案 0 :(得分:3)
我建议你do not validate the date with the regex.而是只检查正确的格式:
/^(\d{6})-[012]\d{4}$/
匹配6个任意数字,短划线,然后是0
到2
的数字,然后是4个任意数字。之后,您将在捕获组编号1
中找到日期部分,您可以在其中查看有效日期。或者,您可以分别提取日,月,年:
/^(\d{2})(\d{2})(\d{2})-[012]\d{4}$/
现在这些日子处于捕获1
,捕获的月份2
,捕获的年份3
。理论上可以使用正则表达式验证日期范围,但实际上并不推荐(正则表达式变得非常臃肿且不可维护)。这就是为什么你应该检查是否有数字,然后你可以使用你的编程语言(PHP或JS)检查给定的数字是否有效。
答案 1 :(得分: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})
任意四位数字请注意,这不会处理某些无效日期的情况,例如2月31日等。这对于正则表达式基本上是不可能的。
答案 2 :(得分: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日,这不是您想要在正则表达式中尝试编码的东西(可以做到,毫无疑问;您只是不想尝试)。
答案 3 :(得分: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日是否有效的日期。最好切断输入并通过some date library运行,所有检查都已实施。