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

例子:

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

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

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


当前回答

来自Java 9+

你可以像这样使用String::replaceAll:

public static void upperCaseAllFirstCharacter(String text) {
    String regex = "\\b(.)(.*?)\\b";
    String result = Pattern.compile(regex).matcher(text).replaceAll(
            matche -> matche.group(1).toUpperCase() + matche.group(2)
    );

    System.out.println(result);
}

例子:

upperCaseAllFirstCharacter("hello this is Just a test");

输出

Hello This Is Just A Test

其他回答

我在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

  package com.test;

 /**
   * @author Prasanth Pillai
   * @date 01-Feb-2012
   * @description : Below is the test class details
   * 
   * inputs a String from a user. Expect the String to contain spaces and    alphanumeric     characters only.
   * capitalizes all first letters of the words in the given String.
   * preserves all other characters (including spaces) in the String.
   * displays the result to the user.
   * 
   * Approach : I have followed a simple approach. However there are many string    utilities available 
   * for the same purpose. Example : WordUtils.capitalize(str) (from apache commons-lang)
   *
   */
  import java.io.BufferedReader;
  import java.io.IOException;
  import java.io.InputStreamReader;

  public class Test {

public static void main(String[] args) throws IOException{
    System.out.println("Input String :\n");
    InputStreamReader converter = new InputStreamReader(System.in);
    BufferedReader in = new BufferedReader(converter);
    String inputString = in.readLine();
    int length = inputString.length();
    StringBuffer newStr = new StringBuffer(0);
    int i = 0;
    int k = 0;
    /* This is a simple approach
     * step 1: scan through the input string
     * step 2: capitalize the first letter of each word in string
     * The integer k, is used as a value to determine whether the 
     * letter is the first letter in each word in the string.
     */

    while( i < length){
        if (Character.isLetter(inputString.charAt(i))){
            if ( k == 0){
            newStr = newStr.append(Character.toUpperCase(inputString.charAt(i)));
            k = 2;
            }//this else loop is to avoid repeatation of the first letter in output string 
            else {
            newStr = newStr.append(inputString.charAt(i));
            }
        } // for the letters which are not first letter, simply append to the output string. 
        else {
            newStr = newStr.append(inputString.charAt(i));
            k=0;
        }
        i+=1;           
    }
    System.out.println("new String ->"+newStr);
    }
}

这是我做的另一种方法

    StringBuilder str=new StringBuilder("pirai sudie test test");

    str.setCharAt(0,Character.toUpperCase(str.charAt(0)));

    for(int i=str.length()-1;i>=0;i--)
    {
        if(Character.isSpaceChar(str.charAt(i)))
            str.setCharAt(i+1,Character.toUpperCase(str.charAt(i+1)));
    }

    System.out.println(str);
public static String toTitleCase(String word){
    return Character.toUpperCase(word.charAt(0)) + word.substring(1);
}

public static void main(String[] args){
    String phrase = "this is to be title cased";
    String[] splitPhrase = phrase.split(" ");
    String result = "";

    for(String word: splitPhrase){
        result += toTitleCase(word) + " ";
    }
    System.out.println(result.trim());
}

这里是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循环。