2014-09-12 45 views
2

比方說,我想驗證一個字符串,以確保它是一個無限長的單個十進制數字整數列表,每個整數都用逗號分隔,並允許零個或多個空格。在正則表達式中,處理分隔列表中的fencepost問題的優雅方式是什麼?

我想使用正則表達式來確保它是有效的。我會用這樣的:

^\d(?:\s*,\s*\d)*$ 

字符串值,將匹配:

"4,0 , 9 ,3, 6" 

該字符串值不匹配:

"4,0 , 9 ,3, 6," 

事實上,這是所期望的行爲。但是,有沒有更好的方法來做到這一點,而不是在正則表達式中重複\ d? (想象一下,\ d是一個更復雜的現實生活正則表達式。)

我想搶佔某些建議。我很清楚,我可以做這些事情:

  • 使用分割功能,內飾空間,並驗證每個元素 反對:

    ^\d$ 
    
  • 一個逗號添加到年底字符串和驗證對:

    ^(?:\d\s*,\s*)+$ 
    
  • 去掉逗號和空格和驗證對:

    ^\d+$ 
    

我如果有一個速記或更優雅的方式編寫正則表達式說只是好奇,「......和處理柵欄柱問題。」

回答

2

可以匹配字符串的開始或像這樣

(?!,)((^|\s*,\s*)\d)+$ 

,或者使用非捕獲組的分隔符...

(?!,)(?:(?:^|\s*,\s*)\d)+$ 

負先行是確保了第一個字符不是,

它擺脫了第二個\d。雖然它更優雅嗎?我想這取決於你。由於\d的簡單性,我認爲它不在這種情況下,但是如果您有一個非常複雜的表達式而不是\d,它可以清理正則表達式。

另一種方式來避免\d兩次將做這樣的事情(我使用C#在我的例子):

string complexExpression = @"\d"; // Whatever your actual expression is 
string regex = string.Format(@"^{0}(?:\s*,\s*{0})*$", complexExpression); 

這完全是人爲的,所產生的表達當然是一樣的,但有人可能會爭辯說,它更像這樣可讀/優雅,而不是100%的正則表達式解決方案。

+0

@trw我編輯了我的答案。您的正則表達式引擎是否支持負向預覽? – Vache 2014-09-12 17:40:57

+0

是的,它的確如此。我明白了,因爲引擎非常渴望,所以前導逗號仍然會匹配'^ | \ s *,\ s *'。謝謝你的負面看法! – trw 2014-09-12 18:01:42