Многострочное сопоставление регулярных выражений Perl в XML-файле с дублирующимися тегами - PullRequest
0 голосов
/ 29 декабря 2011

В конечном итоге я пытаюсь обернуть все непустые элементы файла XML в

'<![CDATA[...]]>'

Вот пример, на котором я тестирую свой код:

<currentTime4 dsi="user 2009/06/02 10:43">10:36</currentTime4>
<todayDate dsi="user 2009/06/02 10:43">06/02/2009</todayDate>
<todayDate3 dsi="user 2009/06/02 10:43">06/02/2009</todayDate3>
<todayDate4 dsi="user 2009/06/02 10:43">06/02/2009</todayDate4>
<currentTime dsi="user 2009/06/02 10:43">10:36</currentTime>
<Relationship dsi="user 2009/06/02 10:43"></Relationship>
<PatSignatureIII dsi="user 2009/06/02 10:43"></PatSignatureIII>
<PatSignatureIV dsi="user 2009/06/02 10:43"></PatSignatureIV>
<PatSignature dsi="user 2009/06/02 10:43">313031320D0A3</PatSignature>
<Relationship dsi="user 2009/06/02 10:43">Mother</Relationship>
<currentTime3 dsi="user 2009/06/02 10:43">10:36</currentTime3>
</consent_to_treat>

Он имитирует XML, с которым мне приходится иметь дело, но в действительности некоторые элементы содержат многострочный текст, что делает это приключение намного более интересным ...

Я сконструировал регулярное выражение, которое работает, пока нет дубликатов:

$text =~ s/(<(\w+) +[" \w\/\-=:]+?>)(?!\n)(.+?)(?<!\n)(<\/\2>)/$1<!\[CDATA\[$3\]\]>$4/gs;

но в этом примере это не так, как показано ниже:

<consent_to_treat dsi="user 2009/06/02 10:43" version="">
<currentTime4 dsi="user 2009/06/02 10:43"><![CDATA[10:36]]></currentTime4>
<todayDate dsi="user 2009/06/02 10:43"><![CDATA[06/02/2009]]></todayDate>
<todayDate3 dsi="user 2009/06/02 10:43"><![CDATA[06/02/2009]]></todayDate3>
<todayDate4 dsi="user 2009/06/02 10:43"><![CDATA[06/02/2009]]></todayDate4>
<currentTime dsi="user 2009/06/02 10:43"><![CDATA[10:36]]></currentTime>
<Relationship dsi="user 2009/06/02 10:43"><![CDATA[</Relationship>
<PatSignatureIII dsi="user 2009/06/02 10:43"></PatSignatureIII>
<PatSignatureIV dsi="user 2009/06/02 10:43"></PatSignatureIV>
<PatSignature dsi="user 2009/06/02 10:43">313031320D0A3</PatSignature>
<Relationship dsi="user 2009/06/02 10:43">Mother]]></Relationship>
<currentTime3 dsi="user 2009/06/02 10:43"><![CDATA[10:36]]></currentTime3>
</consent_to_treat>

Каков наилучший способ сделать его нежадным или, возможно, лучшим решением, отличным от моего?

Заранее спасибо.

P.S. Я полагаю, что я понял это в конце концов. Следующий код, кажется, делает свое дело:

$text =~ s/(<(\w+) +[" \w\/\-=:]+?>)(?!(\n|\s*<\/\2>))(.+?)(?<!\n)(<\/\2>)/$1<!\[CDATA\[$4\]\]>$5/gs;

Еще раз спасибо всем, кто ответил на мой вопрос, и я все еще открыт для лучшего решения ...

1 Ответ

0 голосов
/ 29 декабря 2011

Это регулярное выражение будет делать то, что вам нужно:

s/(<[^>]+>)(.*?)(<\/[^>]+>)/$1<![CDATA[$2]]>$3/gi

код:

#!/usr/bin/perl

my $xml = <<'END_XML';
<currentTime4 dsi="user 2009/06/02 10:43">10:36</currentTime4>
<todayDate dsi="user 2009/06/02 10:43">06/02/2009</todayDate>
<todayDate3 dsi="user 2009/06/02 10:43">06/02/2009</todayDate3>
<todayDate4 dsi="user 2009/06/02 10:43">06/02/2009</todayDate4>
<currentTime dsi="user 2009/06/02 10:43">10:36</currentTime>
<Relationship dsi="user 2009/06/02 10:43"></Relationship>
<PatSignatureIII dsi="user 2009/06/02 10:43"></PatSignatureIII>
<PatSignatureIV dsi="user 2009/06/02 10:43"></PatSignatureIV>
<PatSignature dsi="user 2009/06/02 10:43">313031320D0A3</PatSignature>
<Relationship dsi="user 2009/06/02 10:43">Mother</Relationship>
<currentTime3 dsi="user 2009/06/02 10:43">10:36</currentTime3>
</consent_to_treat>
END_XML

$xml =~ s/(<[^>]+>)(.*?)(<\/[^>]+>)/$1<![CDATA[$2]]>$3/gi;

print $xml;

вывод:

<currentTime4 dsi="user 2009/06/02 10:43"><![CDATA[10:36]]></currentTime4>
<todayDate dsi="user 2009/06/02 10:43"><![CDATA[06/02/2009]]></todayDate>
<todayDate3 dsi="user 2009/06/02 10:43"><![CDATA[06/02/2009]]></todayDate3>
<todayDate4 dsi="user 2009/06/02 10:43"><![CDATA[06/02/2009]]></todayDate4>
<currentTime dsi="user 2009/06/02 10:43"><![CDATA[10:36]]></currentTime>
<Relationship dsi="user 2009/06/02 10:43"><![CDATA[]]></Relationship>
<PatSignatureIII dsi="user 2009/06/02 10:43"><![CDATA[]]></PatSignatureIII>
<PatSignatureIV dsi="user 2009/06/02 10:43"><![CDATA[]]></PatSignatureIV>
<PatSignature dsi="user 2009/06/02 10:43"><![CDATA[313031320D0A3]]></PatSignature>
<Relationship dsi="user 2009/06/02 10:43"><![CDATA[Mother]]></Relationship>
<currentTime3 dsi="user 2009/06/02 10:43"><![CDATA[10:36]]></currentTime3>
</consent_to_treat>
...