2008-12-10 19 views
14

看來,選擇使用字符串解析與正則表達式對我定期來了隨時情況出現,我需要一個字符串的一部分,有關說串等什麼時候最好使用正則表達式而不是基本的字符串分割/子串處理?

的原因,這出現的是我們正在評估肥皂標題的動作之後,它已經通過WCF的OperationContext對象和然後被解析爲可以管理的東西,然後在此基礎上做出決定。現在,簡單的解決方案似乎是保持實現簡單的基本子串,但我的一部分人想知道RegEx會更好還是更健壯。我的另一部分想知道是否使用霰彈槍殺死我們特定情況下的蒼蠅。

所以我不得不問,人們在嘗試決定使用RegEx而不是典型的字符串解析時使用的典型閾值是多少。請注意,我在正則表達式中不是很強大,正因爲如此,我試圖迴避,除非避免引入比我需要的更多併發症是絕對必要的。

如果你不能說出我選擇的縮寫,這是在.NET的土地(C#),但我認爲這並沒有太多的問題。


編輯:好像按我的典型Raybell魅力,我已經在我的問題太羅嗦或誤導性的。我想道歉。我給了一些背景來幫助提供我在做什麼的線索,而不是誤導人們。

我基本上是在尋找關於什麼時候在正則表達式上使用子字符串及其變體的指南,反之亦然。雖然有些答案可能錯過了這個(也是我的錯),但我真的很感激他們,並相應地投了票。

我希望這有助於一些。

+0

除非你另有說明,否則我認爲這個問題回答你提問的同一問題:http://stackoverflow.com/questions/56342/whats-the-best-way-of-parsing-strings – EBGreen 2008-12-10 22:58:30

+0

它接近我在找什麼。我做了搜索,但從未發現任何我認爲合適的東西,儘管這看起來和任何東西都很接近。 – 2008-12-10 23:02:53

+0

我想我問的是如果這個問題給你的信息,你正在尋找? – EBGreen 2008-12-10 23:04:52

回答

21

我的主要準則是使用正則表達式來進行一次性代碼和用戶輸入驗證。或者當我試圖在大量文本中找到特定模式時。對於大多數其他目的,我會編寫一個語法並實現一個簡單的解析器。

一個重要的指導方針(雖然我看到人們一直在嘗試,但真的很難迴避)是在目標語言的語法是遞歸的情況下總是使用解析器。

例如,考慮用於評估括號化算術表達式的小「表達式語言」。在這種語言「程序」的例子是這樣的:

1 + 2 
5 * (10 - 6) 
((1 + 1)/(2 + 2))/3 

一個語法很容易寫,而且看起來是這樣的:

DIGIT := ["0"-"9"] 
NUMBER := (DIGIT)+ 
OPERATOR := ("+" | "-" | "*" | "/") 
EXPRESSION := (NUMBER | GROUP) (OPERATOR EXPRESSION)? 
GROUP := "(" EXPRESSION ")" 

隨着該語法,你可以建立一個遞歸下降解析器在jiffy中。

一個等效的正則表達式是REALLY很難寫,因爲正則表達式通常不會很好地支持遞歸。

另一個很好的例子是JSON攝取。我見過有人試圖用正則表達式來消費JSON,它是INSANE。JSON對象是遞歸的,所以它們只是乞求常規語法和遞歸下降解析器。


hmmmmmmm ...看着其他人的回答,我想我可能已經回答了錯誤的問題。

我將它解釋爲「何時應該使用簡單的正則表達式,而不是全面的解析器?」而大多數人似乎已經把這個問題解釋爲「你應該什麼時候推出自己笨拙的臨時字符驗證方案,而不是使用正則表達式?」

鑑於這種解釋,我的答案是:從來沒有。


好的....多一個編輯。

我會更寬容一點的自己的計劃。只是...不要稱之爲「解析」:o)

我認爲一個好的經驗法則是,如果您可以使用單個謂詞實現所有邏輯,則只應使用字符串匹配基元。就像這樣:

if (str.equals("DooWahDiddy")) // No problemo. 

if (str.contains("destroy the earth")) // Okay. 

if (str.indexOf(";") < str.length/2) // Not bad. 

一旦你的條件包含多個謂詞,那麼你已經開始自己發明特設串驗證語言,你應該正直的人並研究一些正則表達式。

if (str.startsWith("I") && str.endsWith("Widget") && 
    (!str.contains("Monkey") || !str.contains("Pox"))) // Madness. 

正則表達式真的不難學。與像許多關鍵字,原始類型和操作符的C#一樣的huuuuge全功能語言以及包含數千個類的標準庫相比,正則表達式絕對很簡單。大多數正則表達式實現支持大約十幾個操作(給予或帶走)。

這裏有一個很好的參考:

http://www.regular-expressions.info/

PS:作爲獎勵,如果你曾經想學習如何編寫自己的解析器(使用lex/yacc的,ANTLR,JavaCC的,或其他類似的工具),學習正則表達式是一個很好的準備,因爲解析器生成器工具使用許多相同的原則。

6

正則表達式可以

  • 更容易理解
  • 表達更清晰的意圖
  • 短得多
  • 容易改變/適應

在某些情況下,所有這些優點可以通過使用正則表達式來實現,而在其他語言中只有一些可以實現(正則表達式對於e而言並不是很容易理解xample),而在其他情況下,正則表達式更難理解,混淆意圖,時間更長且難以改變。

我從正則表達式中獲得的那些(可能還有其他)優勢越多,我越有可能使用它們。

可能的經驗法則:如果理解正則表達式對於熟悉正則表達式的人需要幾分鐘時間,那麼您不想使用它(除非「正常」代碼更加複雜;-)。

嗯...仍然沒有簡單的經驗法則,對不起。

1

當您所需的轉換不是基本的 - 但仍然在概念上簡單。

沒有理由拉出正則表達式,如果你正在做直字符串替換,例如...它更容易只需使用與string.replace

,另一方面,複雜的規則與許多條件語句或,將採取正則表達式的超過50個字符的特殊情況下,可以是一個噩夢,以維持以後,如果你不明確地寫出來

0

我總是會使用正則表達式,除非它的東西非常簡單,如分裂逗號分離的字符串。如果我認爲有可能有一天字符串可能會變得更復雜,我可能會以一個正則表達式開始。

我不認同正則表達式很難或複雜的觀點。這是每個開發者都應該學習和學習的工具。他們有着無數的用途,而且一旦學會了,這正是您再也不用擔心的事情。

正則表達式很少矯枉過正 - 如果匹配很簡單,正則表達式也是如此。

+0

即使CSV語法分析器的某些東西看起來很複雜,但是給出了引用規則。 (換行符和逗號都可以出現在單個字段中,只要該字段用引號引起來。)不要低估謙虛的CSV!即使使用正則表達式,也很難正確解析:o) – benjismith 2008-12-10 23:06:29

2

[W] e're評估SOAP頭的 行動,對

決策切勿使用正則表達式或基本字符串分析來處理XML。目前常用的每種語言都有完美的XML支持。 XML是一個看似複雜的標準,它不太可能代碼是正確的,因爲它將正確地解析所有格式良好的XML輸入,甚至如果這樣做,你會浪費你的時間,因爲(如剛纔提到的)常見的用法有XML支持。使用正則表達式來解析XML是不專業的。

要回答你的問題,一般來說正則表達式的用法應該儘量減少,因爲它們不可讀。通常,您可以將字符串解析和正則表達式(可能在循環中)組合,以創建比單獨的正則表達式更簡單的解決方案。

1

我同意benjismith說的,但只是想詳細說明一下。對於非常簡單的語法,基本的字符串解析可以很好地工作,但正則表達式也可以。我不會稱之爲矯枉過正。如果它起作用,它就會起作用 - 隨你發現最簡單。而對於中等到中級的字符串解析,正則表達式通常是要走的路。

只要你開始發現自己需要定義一個語法,但是複雜的字符串解析,就可以儘快地使用某種有限狀態機或類似的東西。正則表達式根本不能很好地擴展,使用鬆散的術語。他們變得複雜,難以解釋,甚至無能爲力。

我見過至少有一個項目使用正則表達式不斷增長和增長,很快他們就無法插入新的功能。當它終於到了做新主要版本的時候,他們拋棄了所有的正則表達式,並走上了語法分析器的路線。

0

我想最簡單的方法知道何時使用正則表達式,什麼時候不使用正則表達式時,當您的字符串搜索需要IF/THEN語句或任何類似於這個或那個邏輯的東西時,那麼您需要比簡單的字符串更好的東西比較哪個是正則表達式的亮點。

相關問題