2011-03-17 27 views
1

我知道正則表達式是非常強大的,併成爲他們的專家是不容易的。我們應該在Java中使用正則表達式嗎?

我的一位同事曾經寫過一個java類來解析格式化的文本文件。不幸的是,它在第​​一次集成測試中導致了一個StackOverFlowError。在另一個來自結構化編程世界的同事過來解決它之前,通過消除所有正則表達式,並改爲使用許多嵌套的條件語句以及許多拆分和修剪方法來快速修復它,似乎很難找到該錯誤,並且它工作得非常好!那麼,爲什麼我們需要像Java這樣的編程語言中的正則表達式呢?據我所知,正則表達式的唯一必要用法是文本編輯器中的查找/替換功能。

+2

這取決於...... – codymanix 2011-03-17 14:10:31

回答

4

根據定義,任何可以表達爲正則表達式的東西都可以表示爲IF鏈。您可以使用正則表達式主要有兩個原因:

  • 正則表達式庫傾向於具有優化的實施,大部分的時間會比手工編碼的「IF」鏈對於一些表達式更好。
  • 如果編寫得當,REGEX通常比IF鏈更容易遵循。特別適合更復雜的表情。

如果您的表情太複雜,請使用this answer給出的建議。如果它真的很難理解,請考慮學習如何使用像ANTLR或JavaCC這樣的解析器生成器。一個簡單的語法通常可以代替一個正則表達式,並且維護起來要容易得多。

4

像其他事物一樣:關懷和KISS使用

我用正則表達式很多時候,但我不走在上面,寫100個字符的正則表達式,因爲我知道,我(個人)獲以後再理解......實際上我認爲我的限制大約是30-40個字符,比這大得多的東西讓我花費太多時間在撓頭。

+2

它也聽起來像最終解決方案的代碼複雜性會引起靜態代碼分析工具中的紅旗。一個有據可查的正則表達式是一種權衡,但是擁有巨大的權力將會帶來巨大的責任。我傾向於建立並記錄我的子部分,然後將其組裝成最後一步,當然它們經過廣泛的單元測試。 – 2011-03-17 14:21:32

2

因此,具有多個拆分和修剪方法的多個嵌套條件語句比使用正則表達式的單行或兩行更容易進行調試?

我的首選是正則表達式,因爲一旦你學習它們,它們比解析巨大的嵌套if循環更易於維護和閱讀。

+1

在OP的情況下,REGEX似乎變得太複雜了,所以沒人能調試它。僅使用REGEX僅僅是因爲任務**可以由REGEX解決並不能單獨證明它。有時候其他解決方案可能是更好的選擇。 – codymanix 2011-03-17 14:31:06

1

一如既往,您應該使用最好的工具來完成這項工作。我會用滿足要求的最簡單,易懂,有效的方法來定義「最佳工具」。

經常使用正則表達式會簡化代碼並使其更具可讀性。但情況並非總是如此。

此外,我不會跳到正則表達式導致StackOverflowError的結論。

1

正則表達式是一種工具(與許多其他類似)。當要完成的工作最好使用該工具完成時,您應該使用它。要知道使用哪個工具,它有助於提出一個問題,例如「我什麼時候可以使用正則表達式?」。當然,如果你的工具箱中有許多不同的工具,並且你對它們相當瞭解,決定使用哪種工具會更容易。

1

您可以通過劈裂那些成小塊,像巧妙地使用正則表達式,

final String REGEX_SOMETHING = "something"; 
final String REGEX_WHATEVER = "whatever"; 
.. 
String REGEX_COMPLETE = REGEX_SOMETHING + REGEX_WHATEVER + ... 
+0

這是一個好點! +1 – chance 2011-03-17 14:25:59

+0

不客氣,王先生。 – 2011-03-17 15:17:41

0

正則表達式是在尋找的內容模式非常強大。您當然可以避免使用正則表達式並依賴條件語句,但您很快就會注意到需要多行代碼來完成相同的任務。使用太多的嵌套條件語句會增加代碼的圈複雜度,因此,測試變得更加困難,因爲有太多的分支需要測試。此外,它也使代碼難以閱讀和理解。

當然,你的同事應該有書面測試用例來首先測試他的正則表達式。

這裏沒有正確或錯誤的答案。如果任務很簡單,那麼就不需要使用正則表達式。否則,在這裏和那裏撒上一點正則表達式以使代碼易於閱讀是很好的。

+0

聽起來你並不認爲正則表達式是代碼。 – codymanix 2011-03-17 14:23:37

1

正則表達式可以更容易閱讀,但它們也可能太複雜。這取決於您想要匹配的數據的格式。

Java RE實現仍然存在一些怪癖,其效果是一些非常簡單的表達式(如'((?:[^'\\]|\\.)*)')在匹配較長的字符串時會導致堆棧溢出。因此,確保您使用真實生活數據(以及更極端的示例)進行測試 - 或者使用帶有不同實現的正則表達式引擎(有幾個也是Java庫)。

3

如果您發現正則表達式會變得太複雜且不可修復,請改用代碼。即使對於聽起來非常簡單的事情,正則表達式可能會變得非常複雜。對於在格式MM/DD/YY [yy]所日期的示例驗證爲 「簡單的」 爲:

^(((((((0?[13578])|(1[02]))[\.\-/]?((0?[1-9])|([12]\d)|(3[01])))|(((0?[469])|(11))[\.\-/]?((0?[1-9])|([12]\d)|(30)))|((0?2)[\.\-/]?((0?[1-9])|(1\d)|(2[0-8]))))[\.\-/]?(((19)|(20))?([\d][\d]))))|((0?2)[\.\-/]?(29)[\.\-/]?(((19)|(20))?(([02468][048])|([13579][26])))))$ 

沒有人可以維護。手動解析日期將需要更多的代碼,但可以更加可讀和可維護。

正則表達式非常強大,用於匹配TEXT模式,但對於使用數字部分(如日期)進行驗證不利。

相關問題