我希望连续几年匹配YYYY-YY
。
我正在尝试匹配所有第二个YY
是YYYY
中第3个和第4个字符的位置,其中添加了1个。
到目前为止,我已经{19|20}(\d{2})-(\d{2})
,但不确定如何使用?
参考(1)
,或者我是否正确地采用这种方法并找出不可避免的方法用这种方法“未知的未知数”(如YY99
)?
修改
匹配:1999-00
,2010-11
,2011-12
,2029-30
不匹配:2010-12
,2010-09
,2011-2
,2011-2012
答案 0 :(得分:2)
有两种方式:
困难的方法是使用backrefs。每个小数位需要有10个捕获缓冲区,将被检查。因此,在这种情况下,需要20个。在高级正则表达式引擎中可能有其他方法可以在引擎内执行递归和/或代码执行(eval)。
简单方法,只需抓取数字并进行后期处理。
我不确定您使用的是哪个引擎,所以下面是Perl中的一个示例,用作说明这两种方式的示例。
@samples = qw( 1999-10 1999-00 2010-11 2011-12 2029-30 2010-12 2010-09 2011-2 2011-2012 );
$regex_hard = qr{
^
(?:19|20)
(?:1()|2()|3()|4()|5()|6()|7()|8()|9()|0())
(?:1()|2()|3()|4()|5()|6()|7()|8()|9()|0())
-
(?: \19(?:\1(?:2)|\2(?:3)|\3(?:4)|\4(?:5)|\5(?:6)|\6(?:7)|\7(?:8)|\8(?:9)|\9(?:0)|\10(?:1))
| (?!\19)\d
)
(?:\11(?:2)|\12(?:3)|\13(?:4)|\14(?:5)|\15(?:6)|\16(?:7)|\17(?:8)|\18(?:9)|\19(?:0)|\20(?:1))
$
}x;
for $date (@samples) {
print "$date";
if ($date =~ /$regex_hard/) {
print " ~ matched $&";
}
print "\n";
}
print "\n----------\n";
$regex_easy = qr{ ^ (?:19|20) (\d\d) - (\d\d) $ }x;
print "\n";
for $date (@samples) {
print "$date";
if ($date =~ /$regex_easy/ && $2 == ($1 == 99 ? 0 : $1+1) ) {
print " ~ matched $&";
}
}
输出:
1999-10
1999-00 ~ matched 1999-00
2010-11 ~ matched 2010-11
2011-12 ~ matched 2011-12
2029-30 ~ matched 2029-30
2010-12
2010-09
2011-2
2011-2012
----------
1999-10
1999-00 ~ matched 1999-00
2010-11 ~ matched 2010-11
2011-12 ~ matched 2011-12
2029-30 ~ matched 2029-30
2010-12
2010-09
2011-2
2011-2012
答案 1 :(得分:1)
如果你问我认为你在问什么:
如果两位数年份需要在四位数年份后的一年内,我如何以
YYYY-YY
格式匹配一系列年份?例如,我想匹配1991-92
或2010-11
但不匹配1990-98
,绝对不匹配2009-03
。
然后我认为这不可能与正则表达式(当然不是任何流行或知道的语言或工具)。你最接近它的是使用这样的东西:
(19|20)(\d\d)-(\d\d)
...然后手动或使用代码验证第二个和第三个捕获组在存储,替换或以其他方式处理匹配之前仅具有值1的差异。
修改强>
在参考你的评论时,我不确定做一个蛮力(1972-73|1973-74|1974-75...
)或在潜在的匹配后进行检查以验证数字关系是否更快 - 看起来效率都不高,但似乎有点似乎更好(更灵活)和更令人满意:验证匹配后的算法。效率的答案可能在于你想要支持多少年。
在我做到这一点之前,我需要一点时间来做几件不相关的事情,但是你可以回来看看,其他人可能比我有更多的时间,或者我很快就能做到。 (现在真的更像是code golf type of thing - 你可以尝试一下)
答案 2 :(得分:0)
如果您可以使用AWK,那么可以这样做 -
假设您有一个年份由,
分隔的文件。
[jaypal~/Temp]$ cat years
1999-00,2010-11,2011-12,2029-30,2010-12,2010-09,2011-2,2011-2012
使用SED,您可以将文件设为 -
[jaypal~/Temp]$ sed 's/,/\n/g' years
1999-00
2010-11
2011-12
2029-30
2010-12
2010-09
2011-2
2011-2012
此输出可以通过管道输入AWK以查找连续的年份 -
[jaypal~/Temp]$ sed 's/,/\n/g' years |
awk -F"-" '{a=substr($1,3,2); a=a+1; if (a==$2) print; else if (length(a)>2 && substr(a,2,2)==$2) print}'
1999-00
2010-11
2011-12
2029-30