如何将第一个字母大写并将其余字母小写,同时在完全大写的情况下保持单词大写 - java

How to capitalize first letter and lowercase the rest while keeping the word capital if it is in fully uppercase - java

getSentenceCaseText()

return 当前文本在句子大小写中的字符串表示。句子格是 在句子中使用大写字母或仅将首字母大写的传统方式 单词和任何专有名词。另外,所有大写单词都应该保持原样。

对于此作业,名词仅限于以一个大写字母开头的单词。

**例如字符串“First SenTence.seCOND sentence.tHIRD SENTENCE”

它的输出将是(第一句。第二句。第三句)**


这是我完成上述作业的代码。我可以将每个点后的第一个字母大写并将其余字母设置为小写,但我无法找到如何保持完整的大写单词。

下面是我的代码:

public String getSentenceCaseText(String text) { 
    
    int pos = 0;
    boolean capitalize = true;
    StringBuilder sb = new StringBuilder(text);
    
    while (pos < sb.length()){
         sb.setCharAt(pos, Character.toLowerCase(sb.charAt(pos)));
         if (sb.charAt(pos) == '.') {
            capitalize = true;      
        } else if (capitalize && !Character.isWhitespace(sb.charAt(pos))) {
            sb.setCharAt(pos, Character.toUpperCase(sb.charAt(pos)));   
            capitalize = false;
        }
        pos++;
       }   
   return sb.toString();
}
    

你应该有一个布尔值 - isCapitalize.

起初,这是真的。

在遍历文字的过程中,您应该使用相同的文字创建新的操作文本。

如果isCapitalize标志为真,以首字母大写的方式书写单词。否则,请用小写字母书写。如果整个单词都有大写字母(这就是我们迭代单词的原因)- 将整个单词改成大写字母。

如果您有“.”,则标志仅针对 1 个单词打开。

现在把上面的文字写成代码。 如果您需要帮助,请告诉我们。

您发布的大部分逻辑都可以正常工作。问题是 个单词 像“SENTENCE”,因为您用来检查大小写的逻辑不正确。

最大的问题是您试图遍历 单词 并同时检查该字符串是否大写。

最简单的方法是分离关注点;尝试事先检查 单词 是否大写并采取相应措施。

首先创建一个方法来检查 word 是否大写。例如:

public static boolean isUpper(String s, int start) {
    for(int i = start; i < s.length(); i++) {
        char c = s.charAt(i);
        if(c == '.' || c == ' ')
            return true;
        if (!Character.isUpperCase(c))
            return false;
    }
    return true;
}

此方法接收一个字符串(待检查)和一个 int 值(即, start),告诉该方法来自哪个部分应该开始检查的字符串。

对于 getSentenceCaseText 方法,请遵循以下策略。首先检查当前单词是否大写:

 boolean capitalize = isUpper(text, pos);

如果大写该方法应该跳过这个词并移动到下一个。否则,它会将第一个字符大写并降低其余字符。对文本中的所有单词应用相同的逻辑。

代码可能如下所示:

public static String getSentenceCaseText(String text) {
    int pos = 0;
    StringBuilder sb = new StringBuilder(text);

    // Iterate over the string
    while (pos < sb.length()){
        // First check if the word is capitalized 
        boolean capitalize = isUpper(text, pos);
        char c = sb.charAt(pos);

        // Make the first letter capitalized for the cases that it was not 
        sb.setCharAt(pos, Character.toUpperCase(c));
        pos++;

        // Let us iterate over the word
        // If it is not capitalized let us lower its characters
        // otherwise just ignore and skip the characters 
        for (;pos < sb.length() && text.charAt(pos) != '.' && text.charAt(pos) != ' '; pos++)
            if(!capitalize)
                sb.setCharAt(pos, Character.toLowerCase(sb.charAt(pos)));
       
       // Finally we need to skip all the spaces
       for(; pos < sb.length() && text.charAt(pos) == ' '; pos++ );
    }

    return sb.toString();
}

使用此策略和此代码作为指南,以此为基础并实施您自己的方法。

由于输入字符串可能包含多个句子,需要拆分成句子,然后将每个句子拆分成单词,所有大写的单词保持不变,句子中的第一个单词大写,其余单词单词变成小写。

可以使用正则表达式来完成split a string along with keeping delimiters

static String capitalizeSentence(String input) {
    if (null == input || 0 == input.length()) {
        return input;
    }

    return Arrays
        .stream(input.split("((?<=[.!\?]\s?)|(?=[.!\?]\s?))"))
        .flatMap(sent -> { 
            String[] words = sent.split("((?<=[^\w])|(?=[^\w]))"); 
            return 
                Stream.concat(
                    Stream.of(words[0].matches("[A-Z]+") // process first word
                        ? words[0] 
                        : (Character.toUpperCase(words[0].charAt(0)) + 
                            (words[0].length() > 1 ? words[0].substring(1).toLowerCase() : ""))
                    ),
                    // process the rest of words
                    Arrays.stream(words)
                          .skip(1)
                          .map(word -> word.matches("[A-Z]+") ? word : word.toLowerCase())
                );
        })
        .collect(Collectors.joining());
}

测试:

System.out.println(capitalizeSentence("o! HI!first  SenTence. secOND  sentence. tHIRD: SENTENCE. am I OK?! yes, I am fine!!"));

输出:

O! HI!First  sentence. Second  sentence. Third: SENTENCE. Am I OK?! Yes, I am fine!!

将一个问题拆分成多个小问题是一种很好的做法。所以我建议通过在“。”处拆分文本来处理句子。并遍历句子。

然后在“ ”处分句处理每句的词。

然后检查每个单词是否完全大写。如果是这样,请保持不变。 如果不是,你检查它是否是名词,这里的意思是,它的首字母大写,其他字母没有大写。如果是,则保持不变,否则将其完全转换为小写。

然后(作为最后一步)将每个句子的第一个单词的第一个字母大写。

这样你就不需要任何全局标志了。而且您可以轻松地测试您的算法 - 用于单词和特殊情况,例如句子的开头。如果需要添加其他字符如“.”将文本分成句子 - 简单。 如果你想对其他情况的单词进行特殊处理 - 简单..

将第一个单词设置为大写,其余单词设置为小写

String output = someString.substring(0, 1).toUpperCase() + someString.substring(1).toLowerCase(Locale.ROOT);