我的主要準則是使用正則表達式來進行一次性代碼和用戶輸入驗證。或者當我試圖在大量文本中找到特定模式時。對於大多數其他目的,我會編寫一個語法並實現一個簡單的解析器。
一個重要的指導方針(雖然我看到人們一直在嘗試,但真的很難迴避)是在目標語言的語法是遞歸的情況下總是使用解析器。
例如,考慮用於評估括號化算術表達式的小「表達式語言」。在這種語言「程序」的例子是這樣的:
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的,或其他類似的工具),學習正則表達式是一個很好的準備,因爲解析器生成器工具使用許多相同的原則。
除非你另有說明,否則我認爲這個問題回答你提問的同一問題:http://stackoverflow.com/questions/56342/whats-the-best-way-of-parsing-strings – EBGreen 2008-12-10 22:58:30
它接近我在找什麼。我做了搜索,但從未發現任何我認爲合適的東西,儘管這看起來和任何東西都很接近。 – 2008-12-10 23:02:53
我想我問的是如果這個問題給你的信息,你正在尋找? – EBGreen 2008-12-10 23:04:52