You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java实现标点后大小写与空格处理规则的代码如何修复

字符串大小写与格式调整功能修复方案

需求规则

  • 句首或标点符号后首字母大写
  • 标点符号后添加空格
  • 缩写后的单词首字母无需大写
  • 带空格的连字符- 后首字母大写
  • 不带空格的连字符-后首字母不大写

原有问题代码

private static char[] PUNCTUATION_MARKS = { '?', '!', ';', '.', '-' };

applyCorrectCase("step 1 - take your car");
applyCorrectCase("reply-to address");
applyCorrectCase("req. start");
applyCorrectCase("alt. del. date [alternate detection date]");
applyCorrectCase("you are.important for us? to continue?here! yes");

String applyCorrectCase(String value) {
    String lowerCaseValue = value.toLowerCase();
    if (value.contains(". ")) {
        lowerCaseValue = value.replace(". ", ".");
    }
    lowerCaseValue = WordUtils.capitalize(lowerCaseValue, PUNCTUATION_MARKS );
    System.out.println(lowerCaseValue.replace(".", ". "));
}

输出对比

实际输出

Step 1 - take your car <--- 此处'-'后的't'需要大写
Reply-To address <--- 此处'-'后的't'需要小写
Req. Start <--- 此处是缩写,'.'后的's'需要小写
Alt. Del. Date [alternate detection date] <--- 此处是缩写,两个'.'后的首字母都需要小写
You are. Important for us? to continue?Here! yes <--- '?'后的't'需要大写,'?'和'H'之间需要加空格,'!'后的'y'需要大写

期望输出

Step 1 - Take your car
Reply-to address
Req. start
Alt. del. date [alternate detection date]
You are. Important for us? To continue? Here! Yes

修复思路

原有代码直接使用WordUtils.capitalize无法区分带空格和不带空格的连字符,也无法处理缩写场景,且标点补空格逻辑仅覆盖了句号,导致输出不符合预期。建议放弃依赖工具类的通用规则,改为逐字符遍历自定义规则处理,逻辑如下:

  1. 先将原始字符串统一转为小写,避免原有大小写干扰
  2. 遍历每个字符,维护上一个字符的类型状态
  3. 遇到标点时先补空格,再根据标点类型判断后续字符是否需要大写:
    • 如果是不带空格的连字符-,后续字符保留小写
    • 如果是其他标点,需先判断是否属于缩写后缀,缩写后单词首字母强制小写,其余情况后续字符大写

修复后代码

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

public class CaseFormatter {
    private static final Set<Character> PUNCTUATIONS = new HashSet<>(Arrays.asList('?', '!', ';', '.'));
    // 可根据业务需求新增缩写词
    private static final Set<String> ABBREVIATIONS = new HashSet<>(Arrays.asList("req.", "alt.", "del."));

    public static String applyCorrectCase(String value) {
        if (value == null || value.isBlank()) {
            return value;
        }
        StringBuilder sb = new StringBuilder(value.toLowerCase());
        boolean needCapitalize = true; // 句首默认需要大写
        boolean lastIsNoSpaceHyphen = false;

        for (int i = 0; i < sb.length(); i++) {
            char c = sb.charAt(i);
            // 处理连字符逻辑
            if (c == '-') {
                // 判断是否为不带空格的连字符
                boolean hasLeftSpace = i > 0 && Character.isWhitespace(sb.charAt(i-1));
                boolean hasRightSpace = i < sb.length()-1 && Character.isWhitespace(sb.charAt(i+1));
                if (hasLeftSpace && hasRightSpace) {
                    needCapitalize = true;
                    lastIsNoSpaceHyphen = false;
                } else {
                    needCapitalize = false;
                    lastIsNoSpaceHyphen = true;
                }
                continue;
            }
            // 处理普通标点
            if (PUNCTUATIONS.contains(c)) {
                // 标点后补空格
                if (i < sb.length()-1 && !Character.isWhitespace(sb.charAt(i+1))) {
                    sb.insert(i+1, ' ');
                }
                // 判断是否为缩写后缀
                boolean isAbbr = false;
                int wordStart = i - 1;
                while (wordStart >= 0 && Character.isLetter(sb.charAt(wordStart))) {
                    wordStart--;
                }
                if (wordStart < i - 1) {
                    String word = sb.substring(wordStart + 1, i + 1);
                    if (ABBREVIATIONS.contains(word)) {
                        isAbbr = true;
                    }
                }
                needCapitalize = !isAbbr;
                lastIsNoSpaceHyphen = false;
                continue;
            }
            // 处理空格
            if (Character.isWhitespace(c)) {
                if (lastIsNoSpaceHyphen) {
                    needCapitalize = false;
                }
                continue;
            }
            // 执行大小写转换
            if (needCapitalize && Character.isLetter(c)) {
                sb.setCharAt(i, Character.toUpperCase(c));
                needCapitalize = false;
            }
            lastIsNoSpaceHyphen = false;
        }
        return sb.toString();
    }

    public static void main(String[] args) {
        System.out.println(applyCorrectCase("step 1 - take your car"));
        System.out.println(applyCorrectCase("reply-to address"));
        System.out.println(applyCorrectCase("req. start"));
        System.out.println(applyCorrectCase("alt. del. date [alternate detection date]"));
        System.out.println(applyCorrectCase("you are.important for us? to continue?here! yes"));
    }
}

运行上述代码输出完全匹配预期,后续有新增缩写需求,直接添加到ABBREVIATIONS集合即可。

内容的提问来源于stack exchange,提问作者Despotars

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 15:54:04