【发布时间】:2010-12-23 13:03:38
【问题描述】:
也许正则表达式不是解析这个的最佳方法,如果不是,请告诉我。不管怎样,这里有一些语法树的例子:
(S (CC and))
(SBARTMP (IN once) (NP otherstuff))
(S (S (NP blah (VP blah)) (CC then) (NP blah (VP blah (PP blah))) ))
无论如何,我要做的是将连接词拉出(然后,一次等)及其相应的头(CC,IN,CC),我已经知道每个语法树,因此它可以充当一个锚点,我还需要检索它的父级(第一个是 S,第二个是 SBARTMP,第三个是 S)和它的兄弟姐妹,如果有的话(在第一个没有,在第二个左边的兄弟姐妹中,以及左侧和右侧的第三个兄弟)。不包括高于父级的任何内容
my $pos = "(\\\w|-)*";
my $sibling = qr{\s*(\\((?:(?>[^()]+)|(?1))*\\))\s*};
my $connective = "once";
my $re = qr{(\(\w*\s*$sibling*\s*\\(IN\s$connective\\)\s*$sibling*\s*\))};
此代码适用于:
my $test1 = "(X (SBAR-TMP (IN once) (S sdf) (S sdf)))";
my $test2 = "(X (SBAR-TMP (IN once))";
my $test3 = "(X (SBAR-TMP (IN once) (X as))";
my $test4 = "(X (SBAR-TMP (X adsf) (IN once))";
它会丢弃顶部的 X 并保留其他所有内容,但是,一旦兄弟姐妹中嵌入了东西,它就会不匹配,因为正则表达式没有深入。
my $test = "(X (SBAR-TMP (IN once) (MORE stuff (MORE stuff))))";
我不知道如何解释这一点。我对 Perl 的扩展模式有点陌生,刚开始学习它。为了澄清一下正则表达式的作用:它在两个括号和大写字母/-组合中查找连接词,查找以两个括号结尾的相同格式的完整父级,然后应查找任意数量的兄弟姐妹所有括号都配对。
【问题讨论】:
-
编写的解析器比我想记得的要多,我可以提供以下观察结果:您可以一次解析一个字符,也可以解析不正确。乍一看,正则表达式似乎是一种廉价的解析方式,但要让正则表达式解析器正确可靠几乎总是比艰难的方式做更多的工作。
-
你不能用正则表达式来操作这样的东西。即使由于一些奇怪的扩展在理论上是可能的,但处理这个问题的唯一明智的方法是在内存中重新构建实际的树,然后遍历它。
-
好吧,我就是这么想的,但我想确认一下。无论如何,这似乎是一个很好的起点stackoverflow.com/questions/3693323/… 还有其他建议吗?
-
几个小时前我们刚刚有一个解析示例:stackoverflow.com/questions/4517721/…