拉脱维亚公民个人密码的正则表达式

时间:2012-11-30 18:54:42

标签: php javascript regex

我在为拉脱维亚公民个人代码编写正则表达式(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 个答案:

答案 0 :(得分:3)

我建议你do not validate the date with the regex.而是只检查正确的格式:

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

匹配6个任意数字,短划线,然后是02的数字,然后是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})任意四位数字

http://regexr.com?330dj

请注意,这不会处理某些无效日期的情况,例如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运行,所有检查都已实施。