繁体   English   中英

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”为例

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


这是我上面分配的代码。 我可以将每个点后的第一个字母大写,并将其余字母设置为小写,但我不知道如何保持完整的大写单词。

这是我的代码如下:

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 个回复

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

可以使用正则表达式拆分字符串并保留 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!!

你应该有一个布尔值 - isCapitalize

起初,这是真的。

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

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

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

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

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

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

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

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

2 如何在保持首字母缩写词大写的同时只将每个单词的第一个字母大写?

我正在编写一个函数来自动清理变量名以生成同质变量名。 通常将诸如“This is anExample”之类的内容转换为“This.Is.An.Example”。 通常所有这些都很容易,但是我在处理变量名称中包含的首字母缩略词时遇到了麻烦。 一个例子是:“Clock in Time PST”理想情况 ...

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

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

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

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

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