2011-11-09 15 views
2

私は、次のトリッキーな問題を持っている:私は2つの基本的に同一のテキスト、それらの1つのXMLタグ付きを持ってマージ2とほぼ同様の文章

、他ではありません。

xmlタグを含むテキストのスペルが正規化されていますが、これは嫌です。そのため、私は2つのテキストをマージする方法を探しています。xml-textを、xml-structureを保持している非常に似ていますが、同一ではないプレーンテキストで置き換える必要があります。

誰でも知っていることはありますか? Perlの問題を解決する方法はありますか?

ありがとうございました!

アレックス


正規化されたXML:

<div2> 
<head>Title</head> 
<p>Here is some normalized sample text.</p> 
<p>The orthograph has been changed.</p> 
</div2> 

元のプレーンテキストから:

TITEL

正規化されたサンプルのtexteを次に示します。

オルソグラフが変更されました。

私はこのような出力を持っているしたいと思います:

<div2> 
<head>Title</head> 
<p>Here is some normalised sample texte.</p> 
<p>The ortographe has been changed.</p> 
</div2> 
+0

あなたは何をしたいのかの最小のサンプルを提供することは可能でしょうか?あるいは、私たちはあなたの入力と出力を自分自身で想像してみるべきですか? – FailedDev

+0

[Levenstein distance](http://ja.wikipedia.org/wiki/Levenstein_distance)または同様の基準に基づいて単語を添付できます。 – choroba

+0

申し訳ありませんが、私は最小限のサンプルを提供していません。 –

答えて

0

の単語の同じ数と同じ順序が常に存在する場合 - あなただけの言葉を一つずつ交換することができます。

+0

もちろん、これが作用するかもしれません。しかし、2つの問題が残っている(私は私の技術的な無知を謝ります...私はそれに取り組んでいます):1)私は言葉を置き換えながらxmlタグを無視する必要があります...私はそう取得していないスキル遠い; 2)言葉の順序が全く同じであるかどうかは完全にはわかりません。いくつかの間違い(=違い)があるかもしれませんし、私は気づかずにテキストを台無しにしたくありません。だから、チェックルーチンがいいだろう。私はこのようなものを挿入する方法を見てみるのが良いでしょう。 –

1

ええと...私はこれにAlgorithm::Diffを使用することをお勧めします。あなたは、テキストの変更が点在し、いくつかのXMLタグの挿入があることに気づくでしょう

[+<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>+] 

:あなたは2つのテキストの文字単位の差分を取った場合、基本的に、あなたはこのような何かを得る必要があります。さて、単純に+バージョンのタグと-バージョンのテキストを取った場合は、必要な組み合わせのテキストを取得する必要があります。

XMLタグを単一のトークンとして扱うスマートトークナイザを使用することをおすすめします。 <p>foo</p>は、<p>,f,o,o,</p>に分割される。これは、diffを高速化し、出力をより簡単に解析できるだけでなく、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; 
} 

は私が(例えば、それはタグのネストについて賢くすることができる)このコードを向上させることができたと確信しているが、少なくともそれはあなたのサンプル入力のために動作します。

関連する問題