がんばって調べているんですが、わからないので質問します。

HTMLでのメタキャラクタ(「<」「>」「&」「"」など)を
エスケープしたいんですが、うまくいきません。

試した内容は、こんな感じです。

Stringクラスのreplace(char oldChar, char newChar)
を使えば、上手くいくかなと思ったのですが、文字列の
長さが変わってしまう為、使えませんでした。
1文字と1文字の変換だとうまく行くのですが、今回の
場合、1文字を4文字に変換したい為、使えません^^;
< → &lt;

次に考えたのが、文字列のバッファの長さを増やせる
Stringbufferクラスの
replace(int start, int end, String str)
だと、位置を指定しなければならなくて、どうやったら
良いのかわかりません。

みなさん、どのようにしているのでしょうか?
考え方、サンプルなどありましたら、アドバイスお願いします。

A 回答 (3件)

個人的にHTMLタグを変換する機会が多いので、以下のような関数を


持ったクラスを作って利用してます。

単純にif~elseになるべきところを、switchを使っているだけですが。。。

static public String replaceTag(String argOriginalStr) {
 StringBuffer returnStr = new StringBuffer();

 for (int i = 0; i < argOriginalStr.length(); i++) {
  char ch = argOriginalStr.charAt(i);
   switch(ch) {
    case '<':
     returnStr.append("&lt;");
     break;

    case '>':
     returnStr.append("&gt;");
     break;

    default:
     returnStr.append(ch);
     break;
   }
  }
  return new String(returnStr);
 }
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。

switchで条件分岐するやり方もありましたね!
ほんと、勉強になります。
if文は、結構使用しますが、switch文は、if文に
比べると使用頻度が少なく思います。
ちょっと忘れ気味でした。

お礼日時:2002/03/12 22:05

> そして、さらに質問になりますが、「i+=3」の部分


> なんですが、「&lt;」って4文字なんで、「i+=4」
> にならないのでしょうか?

for() で +1 されるので、+=3 としています。考え方は4文字だから4増やすで良いです。

> しかし、「'」(シングル
> クォーテーション)だけは、エスケープできません。

「お礼」にあったソースで良いと思いますけどね。シングルクォートもきちんと変換できますよね。

ただ、StringBuffer#replace() で置換した後の i を増やすところでは、";" を指しているので、
if の連続ではなく、if ~ else if と続けた方が良いかも。これでも大丈夫ですけど。
    • good
    • 0
この回答へのお礼

またまた、回答ありがとうございます。

>for() で +1 されるので、+=3 としています。

あっ!なるほどです。
合計4増えるんですね。
一人で考えてたら、+=4にして、失敗する所でした。

if~elseの方がいいかもしれませんね。
if~elseに変えて、使ってみたいと思います。

大変、勉強になりました。
最後まで、付き合って頂いて、感謝しております。
ありがとうございました。

「a-kuma」さんの名前は、「あ~熊さん」なのか、
「ええ熊さん」なのか、すごい気になりますが、
「ええ熊さん」だと思っておきます。
「優しい熊さん」という意味で。

すぐに締め切っても良いのですが、他の方で違った
アドバイスがあるよって人がいるかもしれませんので、
明日締め切らせていただきます。
ご了承ください^^

お礼日時:2002/03/11 18:55

> Stringbufferクラスの


> replace(int start, int end, String str)
> だと、位置を指定しなければならなくて、どうやったら
> 良いのかわかりません。

位置は探してゆけば良いですね。例えば、こんな感じ。

StringBuffer buf = new StringBuffer(対象の文字列);
for (int i = 0 ; i < buf.length() ; ++i) {
 if ( buf.charAt(i) == '<' ) {
  buf.replace(i, i+1, "&lt;");
  i += 3;
 }
}

もっとスマートな解が在りそうな気がするので、自信無しとして置きます (^^;

標準の範囲を超えてしまいますが、参考URLのようなライブラリを使えればメソッド一発ですね。

参考URL:http://www.ingrid.org/jajakarta/regexp/jakarta-r …

この回答への補足

素早いご回答ありがとうございます。

考え方がすごいわかりやすかったです。
そして、さらに質問になりますが、「i+=3」の部分
なんですが、「&lt;」って4文字なんで、「i+=4」
にならないのでしょうか?
微妙に混乱しています^^;

また、色々なメタキャラクタをエスケープするように
作ってみました。現在、「クロスサイトスクリプティング」に
ついて対策を考えているのですが、ひとつわからない事が
あります。

「<」「>」「&」「"」の四つの文字については、
エスケープに成功しました。しかし、「'」(シングル
クォーテーション)だけは、エスケープできません。
画面に「&apos;」と出てしまいます。(IE5.5で確認)
シングルクォーテーションのエスケープの仕方が間違って
いるんでしょうか?
それとも、シングルクォーテーションは、普通エスケープ
しないのでしょうか?
クロスサイトスクリプティングの場合は、シングルクォーテーション
は、エスケープしなくても良いのでしょうか?

かなりたくさん、質問となってしまいますので、ご存知
の部分だけでもわかりましたら、よろしくお願いします。

あと、作成したソースを載せますので、書き方などの
注意もありましたら、よろしくお願いします。

try{
for(int i = 0 ; i < sb.length() ; ++i){
if(sb.charAt(i)=='<'){
sb.replace(i, i+1,"&lt;");
i+=3;
}
if(sb.charAt(i)=='>'){
sb.replace(i, i+1,"&gt;");
i+=3;
}
if(sb.charAt(i)=='&'){
sb.replace(i, i+1,"&amp;");
i+=4;
}
if(sb.charAt(i)=='\''){
sb.replace(i, i+1,"&apos;");
i+=5;
}
if(sb.charAt(i)=='<'){
sb.replace(i, i+1,"&quot;");
i+=5;
}
}
}catch(IndexOutOfBoundsException ioobe){
}

補足日時:2002/03/11 11:59
    • good
    • 0
この回答へのお礼

補足部分で、足りない部分と、間違いがあったので、
お礼に書かせてもらいます。
あわてんぼうで、すいません^^;


String str = "<script>test</script>犬&猫<a href=\"http://www.aaa.com\">AAAA</a>";
StringBuffer sb = new StringBuffer(str);

try{
 for(int i = 0 ; i < sb.length() ; ++i){
  if(sb.charAt(i)=='<'){
   sb.replace(i, i+1,"&lt;");
   i+=3;
  }
  if(sb.charAt(i)=='>'){
   sb.replace(i, i+1,"&gt;");
   i+=3;
  }
  if(sb.charAt(i)=='&'){
   sb.replace(i, i+1,"&amp;");
   i+=4;
  }
  if(sb.charAt(i)=='\''){
   sb.replace(i, i+1,"&apos;");
   i+=5;
  }
  if(sb.charAt(i)=='\"'){
   sb.replace(i, i+1,"&quot;");
   i+=5;
  }
 }
}catch(IndexOutOfBoundsException ex){
}

お礼日時:2002/03/11 12:24

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!


このカテゴリの人気Q&Aランキング

おすすめ情報

カテゴリ