我想知道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很容易消化这项任务。
答案 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 ,,并被称为实验性功能。