2009-08-05 18 views
51

Javaを使用して、テキストの行を調べ、すべてのアンパサンド記号(&)をXMLエンティティ参照&に置き換えたいとします。Javaの文字列の文字を置き換えるにはどうすればいいですか?

私はテキストの行を走査してから、テキスト内の各単語をScannerクラスで走査します。次に、単語の各文字を反復するのに、CharacterIteratorを使用します。しかし、私はどのように文字を置き換えることができますか?まず、文字列は不変オブジェクトです。次に、文字(&)を複数の文字(amp&;)に置き換えたいとします。私はこれにどのようにアプローチすべきですか?

CharacterIterator it = new StringCharacterIterator(token); 
for(char ch = it.first(); ch != CharacterIterator.DONE; ch = it.next()) { 
     if(ch == '&') { 

     } 
} 

答えて

100

String.replaceAll()を代わりに使用してください。

String my_new_str = my_str.replaceAll("&", "&"); 
+61

がでReplaceAllには注意してくださいこれは、最初の引数を正規表現として使用するためです。私。 "h.e.l.l.o" .replaceAll( "。"、 "、")はあなたに ",,,,,,,,,"を与えるでしょう! Java 1.5では、新しいString.replace(CharSequence、CharSequence)メソッドがありますが、これは似たようなことですが、最初の引数は正規表現として解釈されません。 –

14
StringBuilder s = new StringBuilder(token.length()); 

CharacterIterator it = new StringCharacterIterator(token); 
for (char ch = it.first(); ch != CharacterIterator.DONE; ch = it.next()) { 
    switch (ch) { 
     case '&': 
      s.append("&"); 
      break; 
     case '<': 
      s.append("&lt;"); 
      break; 
     case '>': 
      s.append("&gt;"); 
      break; 
     default: 
      s.append(ch); 
      break; 
    } 
} 

token = s.toString(); 
+1

このシナリオでは、StringBufferは必要ありません。 –

+1

代わりにStringを使用すると、繰り返しごとに一時的なStringオブジェクトが作成されます。私はあなたに何を提案するか分からない。 –

+0

string.replaceAll? – IRBMe

4

ただ、問題のデータのすべてを含む文字列を作成し、以下のようなString.replaceAll()を使用しています。

String result = yourString.replaceAll("&", "&amp;"); 
+0

データが大きすぎる場合、すべてのデータからなる単一の文字列を作成することは不利になる可能性があります。私たちは行ごとに行うこともできます。 – Bhushan

+0

この場合のreplaceAllの使用は誤っています!可能であれば、replaceAllの代わりにreplaceを必ず使用してください。より効率的でエラーの発生が少ない。 –

0

thisの方法をご覧ください。

+0

置換するパラメータの型(char、char)に注意してください。これは1文字の置換を行います。 – Amber

+0

ええ、ええ、投稿直後に修正されました。 – IRBMe

+0

私はリンクに[1]をインデントする必要があると思います。 –

0

Springを使用している場合は、&から&への変換を処理するHtmlUtils.htmlEscape(String input)を単に呼び出すことができます。

+0

HTMLには純粋なXMLよりも多くのエンティティが定義されているため、危険です。 –

1

文字列をエスケープする場合は、特にユニコードを考慮する場合はcan be trickyを入力します。私は、XMLは、より単純なフォーマット/言語の1つであると考えています。 Apache Commons LangのStringEscapeUtilsクラスとその便利なescapeXmlメソッドを見てみることをお勧めします。

7

また、既に置き換えられたオカレンスを置き換えないことを確認することもできます。これを行うには、否定先読みを伴う正規表現を使用できます。例えば

String str = "sdasdasa&amp;adas&dasdasa";
str = str.replaceAll("&(?!amp;)", "&amp;");

これは、文字列 "sdasdasa & ADAS & dasdasa" ことになります。

正規表現のパターン「&(?!amp;)」は、基本的には次のようになります。「&」の後に「amp;」がない場合は一致します。

82

簡単な答えは:でReplaceAllをするのか

token = token.replace("&", "&amp;"); 

でReplaceAllと比較して、名前にもかかわらず、置き換え、それだけの両方から(ここでは順序であるように思われ、正規表現を使用していませんパフォーマンスと良いプラクティスの観点 - 注意を払っていない特殊文字の要件があるため、偶然に正規表現を使用しないでください)。

Sean Brightの答えは、このコードがパフォーマンス上のホットスポットであることが既に分かっている場合は、パフォーマンスとパフォーマンスのテストに関するさらに別のターゲット要件がないというパフォーマンスの観点から考える価値があります。から来ている。それは確かにdownvotesに値するものではありません。同期が必要な場合を除き、StringBufferの代わりにStringBuilderを使用してください。

言われているように、ここではいくぶん深刻な潜在的な問題があります。文字をエスケープすることは、多くのライブラリがそこで扱っている既知の問題です。 XMLのCDATAセクションにデータをラップするか、実際にXMLを適切に生成するためにXMLライブラリ(JDKに付属のライブラリを含む)を使用することをお勧めします)。

ApacheにはCommons Langの一部としてescaping libraryもあります。

0
//I think this will work, you don't have to replace on the even, it's just an example. 

public void emphasize(String phrase, char ch) 
    { 
     char phraseArray[] = phrase.toCharArray(); 
     for(int i=0; i< phrase.length(); i++) 
     { 
      if(i%2==0)// even number 
      { 
       String value = Character.toString(phraseArray[i]); 
       value = value.replace(value,"*"); 
       phraseArray[i] = value.charAt(0); 
      } 
     } 
    } 
1

このコードを試してください。任意の文字を別の文字で置き換えることができます。 ここで私は手紙を交換すると ''を試してみました " - "文字ギブ列"abcdeaa"

出力のために - > _ bcdef__

public class Replace { 

    public static void replaceChar(String str,String target){ 
     String result = str.replaceAll(target, "_"); 
     System.out.println(result); 
    } 

    public static void main(String[] args) { 
     replaceChar("abcdefaa","a"); 
    } 

} 
関連する問題