如何使用Perl正则表达式解析表示递归数据结构的字符串?

时间:2012-10-05 23:38:05

标签: regex perl tree

我想知道Perl中有哪些方法可以遍历递归结构(例如二叉树) 以字符串形式给出。

更具体地说:

这是一棵树,为简单起见,它是解析树,非常短。 想象它是没有花哨的标签和空格的字符串。

tree(Sentence, 
  tree(NounPhrase,
    leaf(Determiner, "a"),
    leaf(Noun, "man", "singular")
  ), 
  tree(VerbPhrase,
    leaf(Verb, "walks", "present", "3rd person")
  )
)

现在我想访问root的两个直接子节点, 但我不能简单地用正则表达式来做这件事。

m/tree \( \w+ , (group1) , (group2) \) /x

我想正确捕捉group1和group2, 即group1和group2具有偶数个开括号和右括号。

看起来相当复杂的任务,并想知道它的常见/最简单的解决方案是什么?

例如,prolog很容易消化这项任务。

3 个答案:

答案 0 :(得分:2)

我会尝试创建两个函数:sub tree{}sub leaf{}

每个人都会将标记的字词作为字符串返回,例如leaf(Determiner, "a")会返回<Determiner>a</Determiner>

然后只需执行您要处理的文件。输出将是一个类似DOM的结构,您可以使用任何DOM解析器解析,例如XML::DOM

答案 1 :(得分:0)

好的,谢谢,所以答案是 “简单地说,只有RegEx才有可能”。

答案 2 :(得分:0)

如果你知道有多少孩子需要,你的例子是正则表达式所建议的,那么这很容易,这样就足够了:

my @children = m{ tree\(  \w+?, ( (?:tree|leaf)\(.+\) ), ( (?:tree|leaf)\(.+\) ) \) }x;

如果你没有,这似乎更有可能,那么它确实不简单,但它是可能的。在his book on regular expressions中,Jeffrey Friedl建议使用他所谓的动态正则表达式构造来构建递归模式,以匹配嵌套对。

# first, strip your string
s{ ^ tree\( \w+ , (.+) \) $ }{$1}x;

# then, define the recursive pattern to match paired parentheses
my $recursion;
$recursion = qr{ (?> [^()]+ | \( (??{ $recursion }) \) )* }x;

# finally, match!
my @children = m{ ( (?: tree | leaf ) \( $recursion \) ) ,?}gx;

在perlre中,这称为 postponed regular subexpression ,并被称为实验性功能