2017-08-11 18 views
0

工作我有類似這樣perl的非貪婪替換未在開始

<Level1Node> 
. 
. 
    <Level2Node val="Retain"/> 
. 
. 
</Level1Node> 
<Level1Node> 
. 
. 
    <Level2Node val="Replace"/> 
. 
. 
</Level1Node> 
<Level1Node> 
. 
. 
    <Level2Node val="Retain"/> 
. 
. 
</Level1Node> 

我需要刪除只有以下節點的XML,

<Level1Node> 
. 
. 
    <Level2Node val="Replace"/> 
. 
. 
</Level1Node> 

有它非取代-greedy方式中,我使用的正則表達式下面,

perl -0 -pe "s|<Level1Node>.*?<Level2Node val="Retain"/>.*?</Level1Node>||gs" myxmlfile 

但非geedy僅在圖案的端部終止匹配,而不是在開始。如何獲得它開始在<Level1Node>

+0

請發表您的實際意見。在你的正則表達式中,你在正則表達式中提到了' qpulse-hl7-par'但是在你的輸入中沒有'qpulse-hl7-par'和'level2node'屬性,那麼'level2node'是自己關閉的,但是你提到了作爲''在你的正則表達式中。 – mkHun

+0

@mkHun正確更新了正則表達式。 – Kannan

回答

1

您需要使用負前瞻,以確保你不匹配關閉Level1Node標籤,你不希望最後一場比賽:

perl -0 -pe 's|<Level1Node>(?:(?!<\/Level1Node>).)*<Level2Node val="Retain"\/>(?:(?!<\/Level1Node>).)*<\/Level1Node>||gs' tmp.txt 

詳細信息:

<Level1Node> 
(?:(?!<\/Level1Node>).)* # Everything except </Level1Node> 
<Level2Node val="Retain"\/> 
(?:(?!<\/Level1Node>).)* # Everything except </Level1Node> 
<\/Level1Node> 

?:只是使這裏括號不是解釋爲捕獲組。

如果你打算在一個大文件上運行這個,你應該檢查負向視圖的代價,它可能很高。

+0

我剛剛發現了一個解決方案,與您的解決方案几乎相同。太精彩了。謝謝!!! – Kannan

0

使用合適的解析器!它更簡單。

perl -MXML::LibXML -e' 
    my $doc = XML::LibXML->new->parse_file($ARGV[0]); 
    $_->unbindNode() for $doc->findnodes(q{//Level1Node[Level2Node[@val!="Retain"]]}); 
    $doc->toFH(\*STDOUT); 
' tmp.txt