Javaの入力チェックにて、文字種がちょっと複雑なものがあった。
記号、英数、ひらがな、カタカナ、JIS第1水準と第2水準を許可するという要件。
Unicode(UTF-8)のままだは、2バイト文字のチェックが難しい。
なので、1文字ずつgetBytes(“Windows-31J”)した上で範囲チェックする処理を作成した。
/** * 文字種チェック. * @param target チェック対象文字列 * @return 文字種不正 false */ public static boolean checkChar(final String target){ //文字種NGフラグ boolean ngflg; //Stringをchar配列に変換 char[] charArray = target.toCharArray(); //一文字ずつループ処理 for (int i = 0; i < charArray.length; i++) { //エラーフラグをtrueに設定 ngflg = true; char c = charArray[i]; int targetChar = getSJISByte(c); if((0x8140 <= targetChar) && (targetChar <= 0x8396)) { // 1区~5区:OK if (targetChar != 0x8148) { //?でない ngflg = false; } } if((0x889F <= targetChar) && (targetChar <= 0xEAA4)) { // 16区~84区:OK ngflg = false; } if ((0x20 <= targetChar) && (targetChar <= 0x7E)) { // ASCII if (targetChar != 0x23 && targetChar != 0x2B && targetChar != 0x22 && targetChar != 0x5C && targetChar != 0x3C && targetChar != 0x3E && targetChar != 0x3B && targetChar != 0x27 && targetChar != 0x2C) { //# + " \ < > ; ' ,でない ngflg = false; } } if (ngflg) { return false; } } return true; } /** * Shift-JISでバイトに変換する. * @param c 変換対象文字 * @return 変換後文字 */ private static int getSJISByte(final char c) { try { //Windows-31Jでbyteに変換 byte[] bArray = String.valueOf(c).getBytes("Windows-31J"); int targetChar; if (bArray.length == 1) { //1バイト文字 targetChar = bArray[0] & 0xFF; } else { //2バイト文字 targetChar = ((bArray[0] & 0xFF) << 8) | (bArray[1] & 0xFF); } return targetChar; } catch (Exception e) { return 0; } }
途中の「//# + ” \ < > ; ‘ ,でない」の処理は独自の要件のものです。
もっと賢くできるやり方があったら知りたいです。