------ ◆2025/04/11 文字列バイト数...(D1APCommonUtil.getStr()の代替) ------ 次の処理を行うJava言語のメソッド、public static String trimString(String input)を作ってください。 ・inputの各文字を、シフトJISコードと同様に「全角文字は2バイト、半角カナおよびASCII文字は1バイト」と数える。 ・バイト数が12バイト以下ならばinputをそのまま返す。 ・13バイト以上ならば、先頭から12バイトを切り出した文字列を返す。 ・ただし、12バイト目が全角文字の前半部分に当たる場合は、代わりに先頭から11バイトを切り出した文字列を返す。 ------ ChatGPTの回答 ------ public class StringTrimmer { public static String trimString(String input) { if (input == null) return null; int byteCount = 0; int endIndex = 0; for (int i = 0; i < input.length(); i++) { char ch = input.charAt(i); int charBytes; if (isFullWidth(ch)) { charBytes = 2; } else { charBytes = 1; } if (byteCount + charBytes > 12) { break; } byteCount += charBytes; endIndex = i + 1; } // 12バイトちょうどのとき、次の文字が全角文字かどうかをチェック if (byteCount == 12 && endIndex < input.length()) { char nextChar = input.charAt(endIndex); if (isFullWidth(nextChar)) { return input.substring(0, endIndex - 1); // 全角文字が途中で切れるのを避ける } } return input.substring(0, endIndex); } private static boolean isFullWidth(char ch) { // シフトJISにおける全角文字と半角文字の判定の簡易的な実装 // 全角:漢字、ひらがな、カタカナ、全角記号など(U+3000 以上のもの) // 半角:ASCII(U+0000?U+007F)、半角カナ(U+FF61?U+FF9F) return !(ch <= 0x007F || (ch >= 0xFF61 && ch <= 0xFF9F)); } // 簡単なテスト用mainメソッド public static void main(String[] args) { System.out.println(trimString("abcアイウ漢字")); // 半角3+半角カナ3+全角2 = 3+3+4 = 10バイト → そのまま System.out.println(trimString("abcアイウ漢字漢")); // バイト数 12 → そのまま System.out.println(trimString("abcアイウ漢字漢漢")); // バイト数14 → 12バイトまで切り出し(後半の全角注意) } } ------ Claudeの回答 ------ /** * 文字列をShift-JIS的なバイトカウントでトリミングするメソッド * 全角文字は2バイト、半角カナとASCII文字は1バイトとしてカウント * * @param input トリミング対象の文字列 * @return トリミングされた文字列 */ public static String trimString(String input) { if (input == null || input.isEmpty()) { return input; } int byteCount = 0; int charCount = 0; // 文字列の各文字をカウント for (int i = 0; i < input.length(); i++) { char c = input.charAt(i); // ASCII文字と半角カナは1バイト、それ以外(全角文字)は2バイト int charBytes; if (c <= 0x007F || (c >= 0xFF61 && c <= 0xFF9F)) { charBytes = 1; } else { charBytes = 2; } // この文字を追加すると12バイトを超えるかチェック if (byteCount + charBytes > 12) { // 全角文字(2バイト)で13バイト目になる場合は11バイトまでを返す if (charBytes == 2 && byteCount == 11) { return input.substring(0, charCount); } // それ以外は12バイトまでを返す return input.substring(0, charCount); } byteCount += charBytes; charCount++; } // 12バイト以下ならそのまま返す return input; } ------ 最終的にできたソース /** * 文字列srcの(シフトJISコードでの)バイト数を返します。 * @param src 調査対象の文字列。null可です。 * @return シフトJISコードでのバイト数。srcがnullならば0を返します。 */ public static int byteLength(String src){ if(src == null){ return 0; } int len = 0; try { len = src.getBytes("MS932").length; // 以前はSJISにしていた } catch(UnsupportedEncodingException ex){ throw new RuntimeException("Sorry cannot count byte length cause " + "charset 'MS932' is not recognized...", ex); } return len; } /** * 入力文字が全角文字かどうかを判定して返します。 * @param ch * @return */ public static boolean isFullWidth(char ch) { // シフトJISにおける全角文字と半角文字の判定の簡易的な実装 // 全角:漢字、ひらがな、カタカナ、全角記号など(U+3000 以上のもの) // 半角:ASCII(U+0000..U+007F)、半角カナ(U+FF61..U+FF9F) return !(ch <= 0x007F || (ch >= 0xFF61 && ch <= 0xFF9F)); } /** * シフトJISでのバイト数を数える2番目の方法。 * 内部で文字コード変換を行わず、文字種によって1か2をカウントして返します。 * @param src * @return */ public static int customByteLength(String src) { if(src == null){ return 0; } int byteCount = 0; for (int i = 0; i < src.length(); i++) { char c = src.charAt(i); byteCount += isFullWidth(c) ? 2 : 1; } return byteCount; } /** * シフトJISでのバイト数を数える3番目の方法。 * 内部で文字コード変換を行わず、文字種によって1か2をカウントして返します。 * @param src * @return */ public static int customByteLength2(String src) { if(src == null){ return 0; } int byteCount = 0; for (char ch : src.toCharArray()) { // 半角カナやASCII範囲は1バイト、他の日本語(全角)は2バイトとしてカウント if (String.valueOf(ch).matches("[\\p{InBasic_Latin}\\p{InHalfwidth_And_Fullwidth_Forms}]")) { byteCount += 1; } else { byteCount += 2; } } return byteCount; } /** * 指定された文字列inputをシフトJISと同じように「全角文字は2、半角カナまたはASCII文字は1」とバイト数を数えて、 * バイト数がmaxBytes以下ならばそのままを返し、越えるならば先頭からmaxBytesを切り出し、 * omakeStringを末尾に付与して返します。 * ただしmaxBytesバイト目が丁度全角文字の前半部分に当たる場合は、その一つ前の文字までを切り出し、 * omakeStringを末尾に付与して返します。 * @param input 入力文字列 * @param maxBytes 制限する最大バイト数 * @param omakeString 途中までを切り出した際に末尾に付与する文字列。典型的には"..."などを指定することになります。 * @return 出力文字列 */ public static String trimByteString(String input, int maxBytes, String omakeString) { if(input == null){ return null; } int byteCount = 0; int charCount = 0; // 文字列の各文字をカウント for (int i = 0; i < input.length(); i++) { char c = input.charAt(i); // ASCII文字と半角カナは1バイト、それ以外(全角文字)は2バイト int charBytes = isFullWidth(c) ? 2 : 1; if (byteCount + charBytes > maxBytes) { // この文字を追加するとしきい値を超える場合はそこまでで切って返す(おまけつき) return input.substring(0, charCount) + omakeString; } byteCount += charBytes; charCount++; } // バイト数がしきい値以下(丁度を含む)ならそのまま返す(おまけなし) return input; } ------