如何修改代码实现:读取文件并反转长单词字符大小写功能
问题分析与修正方案
咱们来一步步拆解你代码里的核心问题,然后给出针对性的修正:
1. 正则表达式不符合单词定义
你当前用的(?U)(\\w{4,})存在两个关键问题:
\w在Unicode模式下会匹配下划线和数字,但需求里的单词是连续的拉丁或西里尔字符序列,不包含这类符号;- 虽然开启了
(?U)Unicode模式,但\w对西里尔字母的匹配不够精准,应该用\p{L}来匹配任意Unicode字母(涵盖所有语言的字母,完美适配拉丁和西里尔字符)。
所以正则表达式需要改成:
public static final String P13 = "(?U)(\\p{L}{4,})";
\p{L}{4,}表示匹配长度≥4的纯字母序列,刚好满足"长度超过3个字符"的要求,这样你原来写的if (m.group().length() > max)判断就完全多余了,可以直接删掉。
2. 大小写反转逻辑错误
你现在的代码是把匹配到的单词直接转成全大写,但需求是每个字符的大小写单独反转(比如When→wHEN,Информацию→иНФОРМАЦИЮ)。咱们需要写一个辅助方法来处理单个字符的大小写反转:
private static char reverseCase(char c) { if (Character.isUpperCase(c)) { return Character.toLowerCase(c); } else if (Character.isLowerCase(c)) { return Character.toUpperCase(c); } return c; // 非字母字符保持原样(正则已确保是纯字母,这里做兜底处理) }
然后在convert方法里,对每个匹配到的单词逐个字符处理:
public static String convert(String text) { StringBuffer sb = new StringBuffer(); Pattern p = Pattern.compile(P13); Matcher m = p.matcher(text); while (m.find()) { String word = m.group(1); StringBuilder reversedWord = new StringBuilder(); for (char c : word.toCharArray()) { reversedWord.append(reverseCase(c)); } m.appendReplacement(sb, reversedWord.toString()); } return m.appendTail(sb).toString(); }
3. 其他小优化(可选)
你的getInput方法可以用try-with-resources自动关闭Scanner,避免资源泄漏:
public static String getInput(String fileName) throws IOException { StringBuilder sb = new StringBuilder(); try (Scanner scanner = new Scanner(new File(fileName), ENCODING)) { while (scanner.hasNextLine()) { sb.append(scanner.nextLine()).append(System.lineSeparator()); } } return sb.toString().trim(); }
或者用Java 8+的Files类简化文件读取:
public static String getInput(String fileName) throws IOException { return Files.readString(Paths.get(fileName), Charset.forName(ENCODING)).trim(); }
测试验证
用你给出的输入示例测试:
When I was younger So much younger Than today Информацию из файла в верхний регистр
修改后的代码会输出:
wHEN I was YOUNGER So MUCH YOUNGER tHAN TODAY иНФОРМАЦИЮ из ФАЙЛА в ВЕРХНИЙ РЕГИСТР
完全符合需求。
内容的提问来源于stack exchange,提问作者Vanua Aunav
相关产品推荐
相关产品推荐

