我遇到了以下棘手的问题:
我有两个基本相同的文本,其中一个是xml-tagged,另一个不是。
包含xml-tags的文本中的拼写已经规范化 - 这是我不想要的。这就是为什么我在寻找合并两个文本的方法:我必须用非常相似但不完全相同的纯文本替换xml文本,保留xml结构。
有人知道这是否可行?有没有办法解决Perl中的问题?
非常感谢!
亚历
示例
规范化的XML:
<div2>
<head>Title</head>
<p>Here is some normalized sample text.</p>
<p>The orthograph has been changed.</p>
</div2>
来自原始明文:
性标题
这是一些标准化的样本文本。
ortographe已被更改。
我希望得到这样的输出:
<div2>
<head>Title</head>
<p>Here is some normalised sample texte.</p>
<p>The ortographe has been changed.</p>
</div2>
答案 0 :(得分:1)
嗯......我建议使用Algorithm::Diff。基本上,如果你采用两个文本的逐字符差异,你应该得到这样的东西:
[+<div2>+]
[+<head>+]Tit[-e-]l[+e</head>+]
[+<p>+]Here is some normali[-s-][+z+]ed sample text[-e-].[+</p>+]
[+<p>+]The ort[+h+]ograph[-e-] has been changed.[+</p>+]
[+</div2>+]
您会注意到有一些XML标记插入穿插了文本更改。现在,如果你只是从+
版本和-
版本的文本中获取了标记,那么你应该得到你想要的组合文本。
为了达到最佳效果,我建议使用智能标记器将XML标记视为单个标记,以便例如<p>foo</p>
将分为<p>
,f
,o
,o
,</p>
。这不仅使得差异更快,并且更容易解析输出,而且还避免了diff算法可能将标记分成几个块或将其与文本混淆的风险。
以下是一些示例代码:
sub merge_tags {
my ($orig, $tagged) = @_;
# tokenize strings into tags and chars (could use a real XML parser here)
$_ = [/\G(<(?:[^>"']|"[^"]*"|'[^']*')*>|.)/sg] for $orig, $tagged;
require Algorithm::Diff;
my $diff = Algorithm::Diff->new( $orig, $tagged );
my @output;
while ($diff->Next) {
if ($diff->Diff) {
my @text = grep !/^<.*>$/s, $diff->Items(1);
my @tags = grep /^<.*>$/s, $diff->Items(2);
# kluge: output opening tags first
push @output, shift @tags while @tags and $tags[0] !~ /^<\//;
push @output, @text, @tags;
}
else {
push @output, $diff->Same;
}
}
return join "", @output;
}
我确信这段代码可以改进(例如,它可以更聪明地标记嵌套),但至少它适用于您的样本输入。
答案 1 :(得分:0)
如果总是有相同数量的单词和相同的顺序 - 您可以逐个替换单词。