2013-12-16 97 views
0

我們已經給出了一個項目,我們必須接受一組具有非常特殊要求,大約150-200條規則的大文本文件。每個規則都可以通過,失敗,不適用。通過失敗可能是存在或缺乏匹配的正則表達式。有些規則可能是多行的(即如果存在「X」,那麼以下三行也應該存在,它們應該包含1,2和3)。基於Java的基於語法檢查/規則的工具集

雖然整個事情可以寫很難閱讀正則表達式代碼..並且每個規則的整個文件必須重新讀取,我想我會問社區是否有另一種選擇?

我已經看過openrules,drools等等,沒有一個能夠讓它變得比在一個列表中編寫一大套正則表達式並將其應用到文本文件中更容易。

回答

2

我看不出有什麼辦法可以完全避免編寫正則表達式並將它們應用到這些文本文件的行中。 (沒有關於定義配置文件數據的整體語法的指示,根據那個語法編寫解析器會 - 很可能 - 很難,沒有機會?)

我看到兩個問題需要解決。一個是對特定關鍵字(例如「主機名」)的識別,另一個是根據一個或多個先前行,是否存在某些模式。

要解決第一個問題,我會(使用Java代碼)將行分隔成空格分隔的標記,以便每行都變爲List。

第二個問題可以使用規則進行攻擊。

rule "hostname" 
when 
    Line($n: number, $tok: tokens contains "hostname") 
    eval($tok.get($tok.indexOf("hostname") + 1).length() > 4) // incomplete 
then 
    insert(new Correct($n, "hostname")); 
end 

(請注意,布爾表達式必須警惕$托克與「主機名」的結局。)插入事實正確數據比對所有失敗的情況下寫規則更容易。最後會有另一套規則檢查所有需要的正確事實是否在工作記憶中。另外,可能需要檢查重複的「主機名」定義,這可以使用正確的事實輕鬆完成。

我們來看另一個例子。

rule "interface" 
when 
    Line($n1: number, $tok: tokens contains "interface") 
    Line(number == $n1 + 1, tokens not contains "disabled") 
    Line(number == $n1 + 2, 
     tokens not contains "parameter" || 
     tokens contains "parameter" && $tok.indexOf("parameter") < $tok.size() - 1) 
then 
    insert(new Error($n1, "interface configuration error")); 
end 

會不會是$ tok.indexOf( 「參數」)== 1和$ tok.size()== 2是必需的,但不知道這些要求的確切性質......在這裏我m插入一個否定結果,也可以在最後收集它,按行號排序等。

最後一點:我覺得這些驗證要求的措詞太朦朧,除非您有信心更嚴格的處理器能夠處理不良的語法,或者規範實際上容忍奇怪的措辭,例如,例如 「主機名土星沒有他的戒指;-)」 這是一個正確的線?它通過根據您的規則的測試...

0

對於我來說,不是很清楚你告訴我們什麼樣的語法,但是如果你認爲它對於一組正則表達式來說太複雜了,那麼也許你應該爲這個語法編寫一個合適的解析器,例如,優秀的ANTLR

+0

這是大部分配置驗證。每個系統必須有一個'主機名xxxx'行,xxx必須大於4個字符。找到'接口',如果下一行不包含'disabled','description'這個單詞必須存在於下面一行中,並帶有參數....就像一組示例 – awm

0

如果「文本」有什麼規律性,你應該能夠定義一個語法該結構,然後用經典的分析技術來檢查文本堅持結構,經典的語義分析技術來驗證該結構化文本具有其他所需的屬性(例如,您的「有3行包含值1 2 3」)。 (例如,「所有的左圓括號都有對應的右圓括號」,「結構A包含在C中的結構B內部,...」),因此使用語法也可以輕鬆地表達正則表達式無法做到的約束(例如,這是「上下文無關」(語法)與「常規」語言(正則表達式可以識別的)之間的關鍵。

最後,使用語法和分析器意味着您不必在文件上單獨運行正則表達式。良好的解析器生成器將把語法規則組合成一個高效的引擎,無論您擁有多少語法規則,它都能一次挑選出模式。

+0

Ira,我的問題是哪個解析器最適合你正在定義一個結構合理的文本文件。 – awm

+0

您可以使用任何解析器生成器。你在Java中工作; ANTLR或JavaCC可能會很好。作爲一個實際問題,您必須定義一個語法,然後將其折彎以適應解析器生成器的約束條件。 –

0

另一個考慮是讓數據源將數據作爲xml文件發送給您,並且可以使用可以驗證的模式。如果它通過了驗證,那麼您可以解析xml文件並將任何進一步的regexp規則應用於模式無法指定的標記中的數據。如果驗證器不喜歡數據,它會告訴你它不喜歡哪一行(你可以得到一個現成的驗證器,你不必爲自己的驗證器編碼)。這樣,數據源可以確保他們的程序在將數據發送給誰知道有多少客戶之前生成有效數據,並且您的程序可以驗證您是否接受不良數據。我知道它可能不適用於你目前的情況(不得不接受一個文本文件,而不是一個XML文件),但它的未來設計需要考慮。

+0

我想像OP的迴應,「誰將原始文本轉換爲XML,爲什麼不需要解析器呢?」這真的是一場勝利嗎? –

+0

由於它是關於決定的配置信息,我想象的是原始所有者從未想過外部配置驗證,因此沒有簡單的方法來編寫樣式表來涵蓋每種情況。這並不意味着它不能,只是說它很難編寫一個樣式表來驗證然後編寫解析器。 – awm