JSP/Servletのお勉強メモ その11
昨日にひきつづき, テキストエリアへの文章入力で特定のHTMLタグ郡のみを反映させるのをやってる.
タグを許可してるはてなではどうなってんだろう?
今度実験してみよう.
とりあえず, こんなのを.
はてなで利用できるタグ一覧
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
はてなダイアリーのヘルプ - はてなダイアリー利用可能タグ
http://hatenadiary.g.hatena.ne.jp/keyword/%e3%81%af%e3%81%a6%e3%81%aa%e3%83%80%e3%82%a4%e3%82%a2%e3%83%aa%e3%83%bc%e5%88%a9%e7%94%a8%e5%8f%af%e8%83%bd%e3%82%bf%e3%82%b0
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
けっこう, つーか, かなり多い.
びっくりした. formとかも使えるなんて.
昨日書いたものを見直してみて, ビックリするくらいバグだらけだったということに気付く.
まいったまいった.
ちょっと(というか, かなり)修正.
package test.textarea; import java.util.*; public class ProcessInputData { private String input; // 入力文字列 private StringBuffer output; // 出力文字列 private static Hashtable<String, Integer> map = new Hashtable<String, Integer>(); // コンストラクタ public ProcessInputData(){} public ProcessInputData( String input ) { this.input = input + '\n'; // 念のため, 文末に改行をつけておく. this.output = new StringBuffer(); } public String getOutputString(){ return output.toString(); } // タグであれば0以上の値が, そうでなければ, 0が返戻される. private int getTagLength( int start ) { int check = 0; // 検証した文字数 int tag = -1; // タグならば, 0以上の値をとる char c; // 一時保存用 // 最大の長さのタグ, BLOCKQUOTEが10のため, 10個先まで検証. for( int i=1; i<11; i++ ){ // 次の文字が改行, また, 空白だったならば, 終了. c = input.charAt( start+i-1 ); if( c == '\n' || c == ' ' ){ return 0; } try{ // <BLOCKQUOTE .... だったならば, BLOCKQUOTEの部分と一致するかどうか. tag = map.get( input.substring( start, start+i ).toUpperCase() ); } catch( NullPointerException e ){ // Hashtableに登録されていなかった. tag = -1; } if( tag > 0 ){ c = input.charAt( start+i ); if( c == ' ' || c == '>' ){ check = i; break; } tag = -1; } else if ( tag == 0 ){ // コメントだったならば, check = i; break; } } // 行末までに終端タグがあるかどうかを調べる if( check > 0 ){ // ここで"c"が指すものは, ' ', '>'のどちらかのハズ(コメントを除いて). c = input.charAt( start+check ); for( ; c!='>'; check++ ){ if( c == '\n' ){ return 0; } // ここで"c"が指すものは, ' ', '>'のどちらかのハズ(コメントを除いて). c = input.charAt( start+check ); } } return check; } public void processString() { int count = 0; // 入力文字列において読み込んだ文字数 int slash = 1; // 終端タグにつく'/'の分の文字数+1(1が'/'なし, 2が'/'あり) int length = input.length(); // 入力文字列の長さ int taglength = 0; // タグの長さ char c; // 現在読み込んでいる文字 for( count=0; count<length; ++count ){ c = input.charAt(count); switch(c){ case '&': output.append( "&" ); break; case '>': output.append( ">" ); break; case '<': if( input.charAt( count+1 ) == '/' ){ slash = 2; } // slashは最低でも1. // '<', '</'の次の文字を指すようにするため. taglength = getTagLength( count+slash ); if( taglength > 0 ){ // 第2引数で+1としているのは, // substringが書き込む文字列の最終文字の次を指定しなければならないため. output.append( input.substring( count, count+slash+taglength+1 ) ); count += slash+taglength; // 読み込んだ文字数を更新 // 初期状態に戻しておく taglength = 0; } else { output.append( "<" ); } slash = 1; // 必ずslash=1に戻す break; case ' ': output.append( " "); break; case '\"': output.append( """ ); break; case '\'': output.append( "'" ); break; case '\t': output.append( " " ); // タグは空白4つ break; case '\n': output.append( "\n" ); break; default: output.append(c); break; } } } // オブジェクト作成時, 自動で実行される. static { fillMap(); } private static void setTag(String k, Integer v) { map.put( k, v ); } // 値が無い場合はNullPointerExceptionを返す private static void fillMap() { setTag( "!--", 0 ); setTag( "H1", 1 ); setTag( "H2", 2 ); setTag( "H3", 3 ); setTag( "H4", 4 ); setTag( "H5", 5 ); setTag( "H6", 6 ); setTag( "FONT", 7 ); setTag( "BASEFONT", 8 ); setTag( "BIG", 9 ); setTag( "SMALL", 10 ); setTag( "B", 11 ); setTag( "I", 12 ); setTag( "U", 13 ); setTag( "S", 14 ); setTag( "TT", 15 ); setTag( "SUP", 16 ); setTag( "SUB", 17 ); setTag( "BLINK", 18 ); setTag( "P", 19 ); setTag( "BR", 20 ); setTag( "HR", 21 ); setTag( "CENTER", 22 ); setTag( "DIV", 23 ); setTag( "BLOCKQUOTE", 24 ); setTag( "PRE", 25 ); setTag( "XMP", 26 ); setTag( "NOBR", 27 ); setTag( "WBR", 28 ); setTag( "MULTICOL", 29 ); setTag( "SPACER", 30 ); setTag( "UL", 31 ); setTag( "OL", 32 ); setTag( "LI", 33 ); setTag( "DL", 34 ); setTag( "DT", 35 ); setTag( "DD", 36 ); setTag( "A", 37 ); setTag( "TABLE", 38 ); setTag( "TR", 39 ); setTag( "TD", 40 ); setTag( "TH", 41 ); setTag( "CAPTION", 42 ); setTag( "IMG", 43 ); setTag( "MAP", 44 ); setTag( "AREA", 45 ); } }
で, こんなテストプログラムを組んでみる.
package test.textarea; import test.textarea.ProcessInputData; public class ProcessInputDataTest { public static void main(String[] argv) { String input = "てすと<i>てすと</i>\"日本語よ\"" + "\n" + "\'かなーり問題\'ぱやぱや<html>びろーん</html>" + "\n" + "<big>やれやれ</big>うーん<b>えっ</b>" + "\n" + "<!--あらあら-->うふふ<big" + "\n"; ProcessInputData test = new ProcessInputData( input ); test.processString(); String output = test.getOutputString(); System.out.println( "--------------------------------------------------------------------------------" ); System.out.println( "入力データ" ); System.out.println( "--------------------------------------------------------------------------------" ); System.out.println( input ); System.out.println( "--------------------------------------------------------------------------------" ); System.out.println( "出力データ" ); System.out.println( "--------------------------------------------------------------------------------" ); System.out.println( output ); System.out.println( "--------------------------------------------------------------------------------" ); } }
それで結果はこう.
$ java test/textarea/ProcessInputDataTest -------------------------------------------------------------------------------- 入力データ -------------------------------------------------------------------------------- てすと<i>てすと</i>"日本語よ" 'かなーり問題'ぱやぱや<html>びろーん</html> <big>やれやれ</big>うーん<b>えっ</b> <!--あらあら-->うふふ<big -------------------------------------------------------------------------------- 出力データ -------------------------------------------------------------------------------- てすと<i>てすと</i>"日本語よ" 'かなーり問題'ぱやぱや<html>びろーん</html> <big>やれやれ</big>うーん<b>えっ</b> <!--あらあら-->うふふ<big --------------------------------------------------------------------------------
昨日のソースにくらべれば100倍はましなはず.
もっとテストしないと.
色々なまずいパターンが考えられそう.
あと, ソースがそんなに綺麗じゃないのが気になる.
まあ, それはおいおい直していきますか.