2012-12-09 23 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的解释,这解释了为什么我无法在网上找到我的问题的答案。 –