2011-11-23 72 views
0

我想匹配連續年份的YYYY-YY修改參考編號組以匹配

我想匹配所有第二個YYYYYY中的第3個和第4個字符,其中1個已添加到它。

到目前爲止,我已經得到了{19|20}(\d{2})-(\d{2}),但不知道如何使用這種方法使用?參考(1)還是我要對這個正確的方式,找出不可避免的「未知的未知」(如YY99) ?

編輯:

匹配:1999-002010-112011-122029-30
不匹配:2010-122010-092011-22011-2012

+0

請給一些更多的東西例子你正在嘗試匹配什麼可能接近,但不應該匹配 –

+0

好吧,我想我明白了這個問題,但是許多語言在正則表達式中有不同的限制和語法 - 你在使用什麼語言? Java,PHP .Net,JavaScript? –

+1

'1999-00'(如:1999-2000')怎麼樣? – NullUserException

回答

2

有2種方式:

  1. 難的方法是使用backrefs。每個小數位需要有10個捕獲緩衝區,這些緩衝區將被檢查。所以,在這種情況下,需要20個。在引擎內執行遞歸和/或代碼執行(eval)的高級正則表達式引擎中可能還有其他方法可以做到這一點。

  2. 最簡單的方式,只需捕獲數字和做後期處理。

我不確定你使用的是哪個引擎,所以下面是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 
+0

我正在使用JavaScript,所以當你說''後處理''寫一個函數,例如檢查第二個YY減去第一個YY = 1或者有其他邏輯來確認連續的年份。 – StuperUser

+1

已被接受,以表明可能但不可取。 – StuperUser

+0

@SuperUser - 是的,後處理邏輯相當簡單。在Perl中,由於變量的雙重性質,它的一行代碼:'if($ date =〜/ $ regex_easy/&& $ 2 ==($ 1 == 99?0:$ 1 + 1)){//傳遞}' – sln

1

如果你問你問我想什麼:

如何匹配當兩位數年份需要在四位數年份後恰好一年時,格式爲YYYY-YY的年份範圍?例如,我想匹配1991-922010-11,但不是1990-98,絕對不是2009-03

然後我不認爲這是可能的正則表達式(當然不是任何流行的或衆所周知的語言或工具)。你可以來它最接近的是使用這樣的:

(19|20)(\d\d)-(\d\d) 

...然後手動或使用代碼,驗證第二和第三捕獲組只能在之前的1值的差存儲,替換或以其他方式對比賽進行操作。

編輯: 關於你的評論,我不知道它是否會更快做蠻力(1972-73|1973-74|1974-75...)或後做一個潛在的匹配檢查,以驗證數值關係 - 既不似乎特別有效,但似乎稍好一點(更靈活),更令人滿意:驗證賽後比賽的算法。效率的答案可能在於你想支持多少年。

我需要一點時間做幾件無關的事情之前,我這一點,但你可以檢查回來,別人可以有更多的時間比我,或者我會很快得到它。 (這是真的,現在更多的是code golf type of thing反正 - 你可以試試那裏)

+0

是的,這是一個準確的問題。雖然有可能用'(1990-91 | 1991-92 | ... ad nauseum ... | 2099-00)'強制它,但你認爲無法在匹配中驗證'YYYY '和'YY'? – StuperUser

+0

@StuperUser不僅僅是一個標準的正則表達式引擎。不需要。它需要一個專門的引擎(這實際上是非常規的非常規性質)或程序代碼來評估任何_potential_匹配。 –

+0

@CodeJockey對不起,在這裏迂腐,但沒有現代正則表達式引擎實際上是規則的。 – NullUserException

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