2013-12-16 77 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