2012-12-09 53 views
4

我想了解如何在Java中使用正則表達式,並發現以下任務: 編寫一個類來檢查給定的輸入字符串是否是基於BNF形式的這些條件的有效算術術語:Java正則表達式循環引用模式

term = [Vz]summand|[Vz]summand addOp term 
summand = factor | factor mulOp summand 
factor = number | '('term')' 
number = digit | digit number 
digit = '0'|'1'|...|'9' 
vz = '+'|'-' 
addOp = '+'|'-' 
mulOp = '*'|'/' 

利用這些規則,我寫了一些圖案,形似不同的類型:

static Pattern vz = Pattern.compile("[+-]"); 
static Pattern addOp = Pattern.compile("[+-]"); 
static Pattern multOp = Pattern.compile("[*/]"); 
static Pattern digit= Pattern.compile("[0-9]"); 
static Pattern number = Pattern.compile(digit.pattern()+"+"); 
static Pattern factor = Pattern.compile(number.pattern()+"|("+term.pattern()+")"); 
static Pattern summand = Pattern.compile(factor.pattern()+"|"+factor.pattern()+ multOp.pattern()+"\n"); 
static Pattern term = Pattern.compile(vz.pattern()+"?"+summand.pattern()+"|" 
     +vz.pattern()+"?"+summand.pattern()+addOp.pattern()+"\n"); 

你已經看到我的問題:我在因素的definiton參考項目,而不必首先定義。不幸的是,我無法以任何方式切換它。所以我的問題是:

有沒有可能以這種方式引用模式?或者任何其他引用一個模式並在以後定義它?

+0

這是幾乎不可能的任務。您的語法定義了一種可以在任何深度均衡圓括號的語言。這不能由正則表達式來處理。 (換句話說,你的語法是上下文無關的,但不是固定的。)擺脫'factor ='('term')的生產,你可能有機會。 –

+0

@ m.buettner如果你做出了答案,我會鼓勵你。 – Jeff

回答

4

問題是,BNF定義了一個上下文無關語法(它描述的語言比正則表達式描述的語言更復雜)。你將不得不提出一種不同於僅僅使用BNF規則作爲正則表達式模式的方法。

特別是,正確的括號嵌套不規則。一些正則表達式引擎支持(非常規)功能,可以匹配這些功能,但正則表達式通常會變得很長且不可維護。如果Java具有這些功能(例如,PCRE和.NET),我現在還不確定。

如果你想解決手頭的任務,你將不得不手動編寫解析。如果你想學習正則表達式,你必須用另一種語言來做,或者尋找不同的任務。但是,這裏是great source to improve your regex skills

爲了它的樂趣(並告訴你爲什麼正則表達式不是正確的工具,即使引擎支持必要的功能),下面是對應於上述BNF的正則表達式(除了Vz規則,對於一些奇怪的原因,我無法得到它的工作):

^(((\d+|[(](?1)[)])|(?3)[*\/](?2))|(?2)[+-](?1))$ 

(?n)遞歸地嘗試匹配nth子模式(由左括號開到右)計數。

它在PHP中不起作用,但我相信他們的PCRE實現在使用遞歸時有一些回溯問題。在線PCRE測試人員似乎正確處理了一些示例輸入。這裏是自由空間模式(x),帶有一些註釋:

^ 
(    # term (?1) 
    (    # summand (?2) 
    (   # factor (?3) 
     \d+  # number 
    | 
     [(](?1)[)] # (term) 
    )   # end of factor 
    | 
    (?3)[*/](?2) # factor mulOp summand 
)    # end of summand 
| 
    (?2)[+-](?1) # summand addOp term 
)    # end of term 
$ 
+0

謝謝m.buettner的解釋,這解釋了爲什麼我無法在網上找到我的問題的答案。 –