Java中是否内置了一个函数,使字符串中每个单词的第一个字符大写,而不影响其他字符?

例子:

乔恩·斯基特->乔恩·斯基特 miles o'Brien -> miles o'Brien (B仍然是大写,这排除了Title Case) 老麦当劳->

*(老麦当劳也会被发现,但我不指望它有那么聪明。)

快速浏览一下Java字符串文档就会发现只有toUpperCase()和toLowerCase(),它们当然没有提供所需的行为。当然,谷歌的结果主要是这两个函数。它看起来像一个已经被发明出来的轮子,所以问一下也无妨,这样我以后就可以用它了。


当前回答

您也可以非常简单地这样做,并保留任何双空格、前导空格和尾随空格

public static String capitalizeWords(String text) {

    StringBuilder sb = new StringBuilder();
    if(text.length()>0){
        sb.append(Character.toUpperCase(text.charAt(0)));
    }
    for (int i=1; i<text.length(); i++){
        String chPrev = String.valueOf(text.charAt(i-1));
        String ch = String.valueOf(text.charAt(i));

        if(Objects.equals(chPrev, " ")){
            sb.append(ch.toUpperCase());
        }else {
            sb.append(ch);
        }

    }

    return sb.toString();

}

其他回答

worddutil .capitalize(str) (from apache common -text)

(注意:如果你需要“fOO BAr”变成“fOO BAr”,那么用大写的(..)代替)

因为没有人使用regexp,所以我们使用regexp。这个解决方案只是为了好玩。:)(更新:实际上我刚刚发现有一个regexp的答案,无论如何,我想把这个答案留在原地,因为它更好看:)):

public class Capitol 
{
    public static String now(String str)
    {
        StringBuffer b = new StringBuffer();
        Pattern p = Pattern.compile("\\b(\\w){1}");
        Matcher m = p.matcher(str);
        while (m.find())
        {
            String s = m.group(1);
            m.appendReplacement(b, s.toUpperCase());
        }
        m.appendTail(b);
        return b.toString();
    }
}

使用

Capitol.now("ab cd"));
Capitol.now("winnie the Pooh"));
Capitol.now("please talk loudly!"));
Capitol.now("miles o'Brien"));

我在Java 8中编写了一个更具可读性的解决方案。

public String firstLetterCapitalWithSingleSpace(final String words) {
    return Stream.of(words.trim().split("\\s"))
    .filter(word -> word.length() > 0)
    .map(word -> word.substring(0, 1).toUpperCase() + word.substring(1))
    .collect(Collectors.joining(" "));
}

这个解决方案的要点可以在这里找到:https://gist.github.com/Hylke1982/166a792313c5e2df9d31

这里是RxJava解决方案的问题

    String title = "this is a title";
    StringBuilder stringBuilder = new StringBuilder();
    Observable.fromArray(title.trim().split("\\s"))
        .map(word -> word.substring(0, 1).toUpperCase() + word.substring(1).toLowerCase())
        .toList()
        .map(wordList -> {
            for (String word : wordList) {
                stringBuilder.append(word).append(" ");
            }
            return stringBuilder.toString();
        })
        .subscribe(result -> System.out.println(result));

不过我还不喜欢for循环。

    s.toLowerCase().trim();
    result += Character.toUpperCase(s.charAt(0));
    result += s.substring(1, s.indexOf(" ") + 1);
    s = s.substring(s.indexOf(" ") + 1);

    do {
        if (s.contains(" ")) {
            result += " ";
            result += Character.toUpperCase(s.charAt(0));
            result += s.substring(1, s.indexOf(" "));
            s = s.substring(s.indexOf(" ") + 1);
        } else {
            result += " ";
            result += Character.toUpperCase(s.charAt(0));
            result += s.substring(1);
            break;
        }
    } while (true);
    System.out.println(result);