2012-03-26 17 views
0

Javaでは、任意のHTMLドキュメントを文字列として使用しています。簡単にするために、言う:変換前と変換後の文字列のインデックス

String original = "Hello, <strong>this</strong> is a string"; 

そして、私はありませんタグ内に、常にテキスト内の、文字列内のさまざまな場所の記録を持っています。たとえば、 "is"という単語の開始と終了のインデックスは29と31です。

次に、文字列の変換を実行します。この場合、HTMLタグを取り除きます。これは次のようになります。

original = "Hello, this is a string"; 

「今」という単語の新しい開始および終了インデックスを取得するためのエレガントな方法はありますか(12および14)。

考えられる1つの解決策は、元の各インデックスに「フラグ」を挿入し、HTMLを取り除き、その位置を記録しながらフラグを削除することです。インデックスは常にタグの外側にあるので、HTMLのストリッピングに問題はありません。

これが実際に最良の方法であれば、他のHTMLドキュメントでは偶然に起こることのない「フラグ」の良い選択について誰かが推奨していますか?

+0

あなたは言うことができません:startNew = startOld - (lengthNew - lengthOld)? – mfrankli

+0

@mfrankli私は私の例のためにあまりにも単純すぎると思う - 実際には、削除されると、文字列の長さの変化を文字列の先頭からの距離。 –

答えて

1

最良のアプローチは、HTMLタグをどのように取り除いているかに依存します。 <>かっこで囲まれたものをすべて削除するだけであれば、古い文字列をループして、古いインデックスの前に角括弧(<)以外のものを数えることができます。これらの線に沿ったものは、おそらく動作します:

public String newIndex(String str, int oldIndex) { 
    int newIndex = 0; 
    boolean inBracket = false; 
    for (int i = 0; i < str.length(); i++) { 
    if (i == oldIndex) return newIndex; 
    char c = str.charAt(i); 
    if (c == '<') inBracket = true; 
    else if (c == '>') inBracket = false; 
    else if (!inBracket) newIndex++; 
    } 
    return newIndex; 
} 
+0

例をありがとう。理想的には、空白の正規化とhtmlエンティティのデコードを含むため、JSoupのようなものをHTMLを取り除くために使用したいと思いますが、これは間違いなく可能です。 –

+0

もう1つの答えで述べたように、これをHTMLタグを削除するプロセスに変えると、パフォーマンスが向上します。しかし、手でそれをすることは難しいことで有名ですが、予期せぬコーナーケースにぶつかることはありません。あなたのためのマークアップを取り除くために手元にライブラリを持っていて、その代わりにインデックスを出力するのが現実的であれば、私はそのルートを間違いなく推奨します。 – Alex

1

各タグを削除すると、削除したばかりのタグの長さが分かります。そのような各タグについては、の語索引の値がの後に、今すぐ削除したタグのインデックスよりもを探してください。発見されたものについては、タグからタグの長さを引きます。これにより、タグを削除する際にインデックスが同期した状態に保たれ、最後に調整を計算するよりもはるかに簡単になります。

+0

ニース。1つの欠点は、私はもはやHTMLを削除するためにJSoupのようなものを使用することができない、私は正規表現を介して自分自身でそれを行う必要があります。また、これは効率的ではないと感じていますが、それは私の大きな問題ではありません。 –

+0

最初に単語インデックスをどのように取得しますか?タグを取り除いた後に単に収集することはできませんか?あなたが正しいです、効率はそこではうまくいくわけではありませんが、巨大なHTMLソースや膨大な量のページがなければ、その違いはおそらくユーザを傷つけることにはなりません。 – JTeagle

1

主な問題は、Stringが最終的なので(クラスを拡張することはできません)、Stringが使用されているほとんどの場所では、CharSequenceで十分です(実際に独自の実装を作成できます)。

だから、次の2つの選択肢があります。

  1. は、あなたが、あなただけのHTMLを取り除くために必要がある場合は、HTMLタグ

を除去した後、再びHTMLストリッピングコード

  • 再インデックス文書を所有して作成しますこの正規表現を使用することができます:<[^>]+>CDATA blocks<![CDATA[を検索して確認できます)またはインラインJavaScriptを使用していない限り、これは動作することが保証されています(<script>タグsrc属性)。