OKWAVEのAI「あい」が美容・健康の悩みに最適な回答をご提案!
-PR-
解決
済み

メタキャラクタのエスケープについて

  • 困ってます
  • 質問No.232927
  • 閲覧数711
  • ありがとう数3
  • 気になる数0
  • 回答数3
  • コメント数0

お礼率 36% (7/19)

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

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

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

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

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

みなさん、どのようにしているのでしょうか?
考え方、サンプルなどありましたら、アドバイスお願いします。
通報する
  • 回答数3
  • 気になる
    質問をブックマークします。
    マイページでまとめて確認できます。

質問者が選んだベストアンサー

  • 回答No.1
レベル14

ベストアンサー率 50% (1122/2211)

> 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のようなライブラリを使えればメソッド一発ですね。
補足コメント
HELPMAN

お礼率 36% (7/19)

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

考え方がすごいわかりやすかったです。
そして、さらに質問になりますが、「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:50
お礼コメント
HELPMAN

お礼率 36% (7/19)

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


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:08
-PR-
-PR-

その他の回答 (全2件)

  • 回答No.2
レベル14

ベストアンサー率 50% (1122/2211)

> そして、さらに質問になりますが、「i+=3」の部分 > なんですが、「&lt;」って4文字なんで、「i+=4」 > にならないのでしょうか? for() で +1 されるので、+=3 としています。考え方は4文字だから4増やすで良いです。 > しかし、「'」(シングル > クォーテーション)だけは、エスケープできません。 「 ...続きを読む
> そして、さらに質問になりますが、「i+=3」の部分
> なんですが、「&lt;」って4文字なんで、「i+=4」
> にならないのでしょうか?

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

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

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

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

お礼率 36% (7/19)

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

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

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

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

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

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

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


  • 回答No.3

個人的にHTMLタグを変換する機会が多いので、以下のような関数を 持ったクラスを作って利用してます。 単純にif~elseになるべきところを、switchを使っているだけですが。。。 static public String replaceTag(String argOriginalStr) {  StringBuffer returnStr = new StringBuffer(); ...続きを読む
個人的に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);
 }
お礼コメント
HELPMAN

お礼率 36% (7/19)

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

switchで条件分岐するやり方もありましたね!
ほんと、勉強になります。
if文は、結構使用しますが、switch文は、if文に
比べると使用頻度が少なく思います。
ちょっと忘れ気味でした。
投稿日時 - 2002-03-12 22:05:04
このQ&Aのテーマ
このQ&Aで解決しましたか?
-PR-
-PR-
こんな書き方もあるよ!この情報は知ってる?あなたの知識を教えて!
このQ&Aにはまだコメントがありません。
あなたの思ったこと、知っていることをここにコメントしてみましょう。

その他の関連するQ&A、テーマをキーワードで探す

キーワードでQ&A、テーマを検索する
-PR-
-PR-
-PR-

特集


いま みんなが気になるQ&A

-PR-

ピックアップ

-PR-
ページ先頭へ