繁体   English   中英

如何将 rest 的第一个字母大写和小写,同时保持单词大写(如果它是完全大写) - java

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

提示:本站收集StackOverFlow近2千万问答,支持中英文搜索,鼠标放在语句上弹窗显示对应的参考中文或英文, 本站还提供   中文繁体   英文版本   中英对照 版本,有任何建议请联系yoyou2525@163.com。

getSentenceCaseText()

在句子大小写中返回当前文本的字符串表示形式。 句子大小写是在句子中使用大写字母或仅将第一个单词和任何专有名词大写的传统方式。 此外,所有大写单词应保持原样。

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

**例如字符串“First Sentence.secOND sentence.tHIRD SENTENCE”

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


这是我完成上述任务的代码。 我可以将每个点后的第一个字母大写并将 rest 设置为小写,但我不知道如何保持完整的大写单词。

这是我下面的代码:

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();
}
    
4 个回复

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

可以使用正则表达式来拆分字符串并保留分隔符

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!!"));

Output:

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

你应该有一个 boolean - isCapitalize

起初,这是真的。

在迭代文本期间,您应该使用相同的词创建新的操作文本。

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

如果您有“.”,则该标志仅打开 1 个字。

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

您发布的大多数逻辑都可以正常工作。 问题是像“SENTENCE”这样的,因为您用来检查大小写的逻辑不正确。

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

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

首先创建一个仅检查单词是否大写的方法。 例如:

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();
}

使用此策略和此代码作为指导,在此基础上构建并实现您自己的方法。

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

然后你通过在“”处拆分句子来处理每个句子的单词。

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

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

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

5 如何找到一个单词 - 第一个字母大写,其他字母小写

问题陈述:从完整的文本集中过滤这些单词,第一个字母大写,其他所有字母小写。 将结果存储在变量 title_words 中。 打印 title_words 中存在的单词数。 我已经尝试了所有可能的方法来找到答案,但不知道我落后于哪里。 我也试过这种方式: 我不确定需要多少计数,无论计数即将到 ...

6 Elixir 仅大写单词的第一个字母

我有一个字符串,我只需要大写第一个字母。 我还需要保留任何后续信件的大小写。 一开始我以为: 会成功的。 但除了修复第一个字母外,它还会将字母的 rest 小写。 我最终需要的是“超文本”。 我最初的通行证是: 这工作得很好,但它确实看起来很冗长,也需要做很多工作。 我一直觉得有更好的方法。 我只是 ...

9 将括号内的每个单词的第一个字母大写

我正在尝试为Tagscanner(Windows上的音乐标记器)编写一些有用的Regex,并在regex101.com上花了很多时间来实现我的想法。 在像法语这样的语言中,如果你把每个单词都弄清楚,那么让标题看起来很好是一件非常痛苦的事情。 我只想把圆括号中每个单词的第一个字母大写。 ...

2019-04-03 21:39:58 1 31   regex
10 查找包含大写第一个字母的单词

我正在尝试在字符串中找到单个或组合在一起的单词。 例如: 我想拿出来,所以我的结果如下。 到目前为止我的正则表达式是这样的 这会找到大写单词,但只将它们分开包含空格。 如何控制正则表达式连续接受1到3个单词,用大写字母 ? ...

2015-11-25 10:33:48 3 614   c#/ regex
暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2022 STACKOOM.COM