我有一个像这样的XML文件结构:
<word id="15" pos="SS">
<token>infarto</token>
<lemmas>infarto</lemmas>
</word>
<word id="16" pos="AS">
<token>miocardico</token>
<lemmas>miocardico</lemmas>
</word>
<word id="17" pos="AS" annotated="head">
<token>acuto</token>
<lemmas>acuto</lemmas>
</word>
<word id="18" pos="E">
<token>in</token>
<lemmas>in</lemmas>
</word>
<word id="19" pos="SS">
<token>corso</token>
<lemmas>corso</lemmas>
</word>
我正在尝试做的是获取围绕具有单词id 17(注释=“头部”)的单词的“pos”和“token”的值。
对于第17行之后的所有比赛,这都没有问题。
(pos=")(.+)(")(\s\S+?)("head")([\s\S]+?)(>)(\w+?)(<+)([\S\s]+?)(pos=")(.+)(")([\s\S]+?) (token>)(.+)(<)([\s\S]+?)
这可以获取我想要的所有信息,如果我想扩展,我可以添加
(pos=")(.+)(")([\s\S]+?)(token>)(.+)(<)([\s\S]+?)
到最后。它不漂亮,但它有效。
现在,当我想要走向另一个方向时,我绝对难倒
(pos=")(.+)(")([\s\S]+?)(token>)(.+)(<)([\s\S]+?)(pos=")(.+)(")(\s\S+?)("head")
它不匹配单词16的信息(“注释头”前面的第一个),而是匹配之前的所有信息(单词15,单词14,单词13等)。
我错过了什么?
P.S。 遗憾的是,使用XML解析器不是一种选择。
答案 0 :(得分:0)
如果您确定您的数据是格式良好的XML。我认为这是可能的,尝试这些步骤:
第1步:<word[^>]*>([^<]*(?:(?!<\/?word)<[^<]*)*)<\/word>
(参考http://regexr.com?31org)
第2步:从第1步(第1组)获取字符串,并与<token[^>]*>([^<]*(?:(?!<\/?token)<[^<]*)*)<\/token>
(参考http://regexr.com?31ora)或<lemmas[^>]*>([^<]*(?:(?!<\/?lemmas)<[^<]*)*)<\/lemmas>
(参考http://regexr.com?31ord)
您可以尝试根据您的要求修改这些模式:)
参考:掌握正则表达式3
答案 1 :(得分:0)
我认为它应该是这样的:
(?s)(<word(?:(?!<word).)*)<word[^>]*?annotated="head".*?(<word[^>](?:(?<!</word>).)*)
因此,组#1将包含id = 16的节点“word”,组#2将包含id = 18的节点“word”。
然后,您可以使用正则表达式分别解析每个节点,如下所示:
(?s)<word[^>]*?pos="(?P<pos>[^"]+).*?<token>(?P<token>[^<]+)
你会得到两组'pos'和'token'。
当然可以使用单个正则表达式,但它会非常难看。