Java新手求助:StringBuilder使用与colors.txt颜色格式验证问题
嘿,作为Java新手,在使用StringBuilder时遇到问题太正常啦!我来帮你搞定这个颜色验证和格式化的需求,咱们一步步来:
先明确规则细节
先把你给出的需求拆解清楚,避免踩坑:
- 输入格式分两种:带
(#)前缀的(比如(#)F3C)和不带前缀的(比如095) - 有效性判断:去掉前缀后的核心颜色码,必须全由十六进制字符组成(0-9、a-f、A-F),包含非十六进制字符则判定无效
- 格式化规则:
- 把核心颜色码补全为6位十六进制(短写法规则):
- 3位码(如
F3C):每个字符重复一次 →FF33CC - 6位码(如
aa4256):直接转大写保留 →AA4256 - 4位码(如
60CC):按你的例子逻辑,每个字符重复一次后取前6位 →6600CC - 1位码(如
0):重复6次 →000000
- 3位码(如
- 补全后添加
FF作为alpha通道 - 最终输出用括号包裹,可按需选择是否保留
#(匹配你给出的例子格式)
- 把核心颜色码补全为6位十六进制(短写法规则):
用StringBuilder实现核心逻辑
StringBuilder在字符串拼接、修改场景下效率比直接用+号高很多,下面是完整代码实现:
import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; import java.util.regex.Pattern; public class ColorValidator { // 匹配十六进制字符的正则表达式 private static final Pattern HEX_PATTERN = Pattern.compile("^[0-9a-fA-F]+$"); public static void main(String[] args) { // 读取colors.txt文件,自动关闭流避免资源泄漏 try (BufferedReader reader = new BufferedReader(new FileReader("colors.txt"))) { String line; while ((line = reader.readLine()) != null) { line = line.trim(); if (line.isEmpty()) continue; // 跳过空行 String result = processColor(line); System.out.println(line + " → " + result); } } catch (IOException e) { System.err.println("读取文件出错:" + e.getMessage()); } } private static String processColor(String input) { StringBuilder sb = new StringBuilder(); String coreColor; // 第一步:提取核心颜色码(去掉可能的(#)前缀) if (input.startsWith("(#)")) { coreColor = input.substring(3).trim(); } else { coreColor = input.trim(); } // 第二步:验证核心颜色码是否为有效十六进制字符 if (!HEX_PATTERN.matcher(coreColor).matches()) { return "无效,包含非十六进制字符"; } // 第三步:补全为6位十六进制 String sixDigitColor; int length = coreColor.length(); switch (length) { case 1: sixDigitColor = coreColor.repeat(6).toUpperCase(); break; case 3: sb.setLength(0); // 清空StringBuilder复用 for (char c : coreColor.toCharArray()) { sb.append(c).append(c); } sixDigitColor = sb.toString().toUpperCase(); break; case 6: sixDigitColor = coreColor.toUpperCase(); break; case 4: sb.setLength(0); for (char c : coreColor.toCharArray()) { sb.append(c).append(c); } sixDigitColor = sb.toString().toUpperCase().substring(0, 6); break; default: return "无效,颜色码长度不符合要求"; } // 第四步:拼接最终输出格式(按需调整是否保留#) sb.setLength(0); // 若不需要#,把"(#"改成"("即可 sb.append("(#").append(sixDigitColor).append("FF)"); return sb.toString(); } }
代码说明
- 正则验证:用
Pattern快速判断核心颜色码是否合法,比逐个字符判断更简洁高效 - StringBuilder复用:通过
setLength(0)清空已有内容,避免频繁创建新对象,提升性能 - 文件读取:使用
try-with-resources语法自动关闭流,避免资源泄漏 - 格式灵活调整:如果你的输出不需要
#,只需要修改最后拼接的前缀即可
测试你的示例
- 输入
(#)F3C→ 输出(#FF33CCFF)(与你的要求一致) - 输入
(#)aa4256→ 输出(#AA4256FF)(若不需要#可改为(AA4256FF)) - 输入
(#)ag0933→ 输出无效,包含非十六进制字符 - 输入
(#)60CC→ 输出(#6600CCFF)(与你的要求一致) - 输入
095→ 输出(#009955FF)
如果有其他特殊长度的颜色码需要支持,直接在switch中添加对应case即可。
内容的提问来源于stack exchange,提问作者Jason Glenn
相关产品推荐
相关产品推荐

