我有一些我希望根据标签匹配的文字只出现一次。 文本如下(一些随机字符可以包含除标签之外的任何内容):
<tag1><tag2><tag3>Some randome chars</tag3><tag3>Some randome chars</tag3><tag3>Some randome chars</tag3><tag3>Some randome chars</tag3></tag2></tag1>
<tag1><tag2><tag3>Some randome chars</tag3></tag2></tag1>
<tag1><tag2><tag3>Some randome chars</tag3><tag3>Some randome chars</tag3><tag3>Some randome chars</tag3></tag2></tag1>
<tag1><tag2><tag3>Some randome chars</tag3><tag3>Some randome chars</tag3></tag2></tag1>
<tag1><tag2><tag3>Some randome chars</tag3></tag2></tag1>
<tag1><tag2><tag3>Some randome chars</tag3><tag3>Some randome chars</tag3><tag3>Some randome chars</tag3><tag3>Some randome chars</tag3><tag3>Some randome chars</tag3><tag3>Some randome chars</tag3></tag2></tag1>
<tag1><tag2><tag3>Some randome chars</tag3><tag3>Some randome chars</tag3><tag3>Some randome chars</tag3><tag3>Some randome chars</tag3><tag3>Some randome chars</tag3></tag2></tag1>
<tag1><tag2><tag3>Some randome chars</tag3><tag3>Some randome chars</tag3><tag3>Some randome chars</tag3><tag3>Some randome chars</tag3></tag2></tag1>
我想要的匹配是:匹配tag2中只出现一次的tag3。
例如:
<tag2><tag3>something</tag3></tag2> is matched
<tag2><tag3>something</tag3><tag3>something</tag3></tag2> isn't matched
根据以上文字,预期输出为:第2行和第5行。
我试过的正则表达式(没有工作):
<tag2><tag3>(.*)?</tag3></tag2>
<tag2><tag3>(.*){1}</tag3></tag2>
答案 0 :(得分:4)
我会敦促你不要使用正则表达式来操纵XML。正则表达式无法处理像XML这样的上下文语言,因此您构建了脆弱的代码 - 对XML格式(例如whitespacing)的完全有效的更改可能会中断。
所以相反:
#!/usr/bin/env perl
use strict;
use warnings;
use XML::Twig;
my $twig = XML::Twig->parse( \*DATA );
foreach my $element ( $twig->get_xpath('//tag2') ) {
if ( scalar $element->children('tag3') == 1 ) {
$element->print;
print "\n";
}
}
__DATA__
<root>
<tag1><tag2><tag3>Some randome chars</tag3><tag3>Some randome chars</tag3><tag3>Some randome chars</tag3><tag3>Some randome chars</tag3></tag2></tag1>
<tag1><tag2><tag3>Some randome chars</tag3></tag2></tag1>
<tag1><tag2><tag3>Some randome chars</tag3><tag3>Some randome chars</tag3><tag3>Some randome chars</tag3></tag2></tag1>
<tag1><tag2><tag3>Some randome chars</tag3><tag3>Some randome chars</tag3></tag2></tag1>
<tag1><tag2><tag3>Some randome chars</tag3></tag2></tag1>
<tag1><tag2><tag3>Some randome chars</tag3><tag3>Some randome chars</tag3><tag3>Some randome chars</tag3><tag3>Some randome chars</tag3><tag3>Some randome chars</tag3><tag3>Some randome chars</tag3></tag2></tag1>
<tag1><tag2><tag3>Some randome chars</tag3><tag3>Some randome chars</tag3><tag3>Some randome chars</tag3><tag3>Some randome chars</tag3><tag3>Some randome chars</tag3></tag2></tag1>
<tag1><tag2><tag3>Some randome chars</tag3><tag3>Some randome chars</tag3><tag3>Some randome chars</tag3><tag3>Some randome chars</tag3></tag2></tag1>
</root>
这将处理格式化的XML,但也只是在一行上。或者像这样:
<root>
<tag1>
<tag2>
<tag3>Some randome chars</tag3>
<tag3>Some randome chars</tag3>
<tag3>Some randome chars</tag3>
<tag3>Some randome chars</tag3>
</tag2>
</tag1>
<tag1>
<tag2>
<tag3>Some randome chars</tag3>
</tag2>
</tag1>
<tag1>
<tag2>
<tag3>Some randome chars</tag3>
<tag3>Some randome chars</tag3>
<tag3>Some randome chars</tag3>
</tag2>
</tag1>
<tag1>
<tag2>
<tag3>Some randome chars</tag3>
<tag3>Some randome chars</tag3>
</tag2>
</tag1>
<tag1>
<tag2>
<tag3>Some randome chars</tag3>
</tag2>
</tag1>
<tag1>
<tag2>
<tag3>Some randome chars</tag3>
<tag3>Some randome chars</tag3>
<tag3>Some randome chars</tag3>
<tag3>Some randome chars</tag3>
<tag3>Some randome chars</tag3>
<tag3>Some randome chars</tag3>
</tag2>
</tag1>
<tag1>
<tag2>
<tag3>Some randome chars</tag3>
<tag3>Some randome chars</tag3>
<tag3>Some randome chars</tag3>
<tag3>Some randome chars</tag3>
<tag3>Some randome chars</tag3>
</tag2>
</tag1>
<tag1>
<tag2>
<tag3>Some randome chars</tag3>
<tag3>Some randome chars</tag3>
<tag3>Some randome chars</tag3>
<tag3>Some randome chars</tag3>
</tag2>
</tag1>
</root>
或者像这样:
<root
><tag1
><tag2
><tag3
>Some randome chars</tag3><tag3
>Some randome chars</tag3><tag3
>Some randome chars</tag3><tag3
>Some randome chars</tag3></tag2></tag1><tag1
><tag2
><tag3
>Some randome chars</tag3></tag2></tag1><tag1
><tag2
><tag3
>Some randome chars</tag3><tag3
>Some randome chars</tag3><tag3
>Some randome chars</tag3></tag2></tag1><tag1
><tag2
><tag3
>Some randome chars</tag3><tag3
>Some randome chars</tag3></tag2></tag1><tag1
><tag2
><tag3
>Some randome chars</tag3></tag2></tag1><tag1
><tag2
><tag3
>Some randome chars</tag3><tag3
>Some randome chars</tag3><tag3
>Some randome chars</tag3><tag3
>Some randome chars</tag3><tag3
>Some randome chars</tag3><tag3
>Some randome chars</tag3></tag2></tag1><tag1
><tag2
><tag3
>Some randome chars</tag3><tag3
>Some randome chars</tag3><tag3
>Some randome chars</tag3><tag3
>Some randome chars</tag3><tag3
>Some randome chars</tag3></tag2></tag1><tag1
><tag2
><tag3
>Some randome chars</tag3><tag3
>Some randome chars</tag3><tag3
>Some randome chars</tag3><tag3
>Some randome chars</tag3></tag2></tag1></root>
在语义上与您的相同。
答案 1 :(得分:2)
你的正则表达式不起作用,因为你允许捕获组中的所有内容(.
)。这非常贪婪,会尽可能地停留在最后</tag3>
。如果您只想匹配不能包含标签的内容,则需要匹配除开始标记令牌之外的任何内容。
m{<tag2><tag3>([^<]+)</tag3></tag2>}g
在regex101.com上试用。
答案 2 :(得分:1)
使用XML感知工具。我在xsh中尝试了以下内容,这是XML::LibXML:
的包装器ls //tag2[1=count(tag3)]
在为tag2添加行号后,我得到了
<tag2>2<tag3>Some randome chars</tag3></tag2>
<tag2>5<tag3>Some randome chars</tag3></tag2>