25

I searched high and low but could only find indirect references to this type of question. When developing an android application, if you have a string which has been entered by the user, how can you convert it to title case (ie. make the first letter of each word upper case)? I would rather not import a whole library (such as Apache's WordUtils).

Russ
  • 3,768
  • 7
  • 28
  • 37
  • when you wer knowing the answer then y did u asked a question here ? – Shruti Sep 12 '12 at 11:49
  • 3
    @Shruti: This behavior is by design. http://blog.stackoverflow.com/2011/07/its-ok-to-ask-and-answer-your-own-questions/ – SLaks Sep 12 '12 at 11:50
  • 1
    @Shruti There's nothing wrong with answering your own questions. Stackoverflow isn't just for finding solutions to your own problems, the main point should be providing useful questions and answers for *future* users who have the same problem. – Anthony Grist Sep 12 '12 at 11:54

16 Answers16

40
     /**
     * Function to convert string to title case
     * 
     * @param string - Passed string 
     */
    public static String toTitleCase(String string) {

        // Check if String is null
        if (string == null) {
            
            return null;
        }

        boolean whiteSpace = true;
        
        StringBuilder builder = new StringBuilder(string); // String builder to store string
        final int builderLength = builder.length();

        // Loop through builder
        for (int i = 0; i < builderLength; ++i) {

            char c = builder.charAt(i); // Get character at builders position
            
            if (whiteSpace) {
                
                // Check if character is not white space
                if (!Character.isWhitespace(c)) {
                    
                    // Convert to title case and leave whitespace mode.
                    builder.setCharAt(i, Character.toTitleCase(c));
                    whiteSpace = false;
                }
            } else if (Character.isWhitespace(c)) {
                
                whiteSpace = true; // Set character is white space
            
            } else {
            
                builder.setCharAt(i, Character.toLowerCase(c)); // Set character to lowercase
            }
        }

        return builder.toString(); // Return builders text
    }
David Kariuki
  • 1,522
  • 1
  • 15
  • 30
Codeversed
  • 9,287
  • 3
  • 43
  • 42
  • Great, but for anyone who wants to cover if the writer omitted a space prior to a new sentence, you can change it to => else if (Character.isWhitespace(c) || c == '.' || c == '!' || c == '?') { space = true; } – Ben Dec 08 '18 at 13:58
  • Thanks.. Worked liked a charm..;) – MashukKhan Apr 02 '19 at 14:04
17

You're looking for Apache's WordUtils.capitalize() method.

Kiirani
  • 1,067
  • 7
  • 19
SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
  • Yes, but as I said, I didn't really want to import a whole library just for this. – Russ Sep 12 '12 at 12:02
  • 3
    I'm upvoting this, even though it violates the parameters of the question. As the OP mentioned, this is the only stack overflow question that really addresses this problem on Android, and I think the possibility of using Apache commons should be mentioned in the answers section as an alternative, rather than just in passing in the question itself. – Kiirani Jul 10 '13 at 07:09
  • @Russ consider adding Apache lib commons, it's only ~200Kb but it's super handy! I would say that in most of the projects you will re-invent some of those methods with 99% probability. – Kirill Karmazin Mar 28 '19 at 12:48
16

I got some pointers from here: Android,need to make in my ListView the first letter of each word uppercase, but in the end, rolled my own solution (note, this approach assumes that all words are separated by a single space character, which was fine for my needs):

String[] words = input.getText().toString().split(" ");
StringBuilder sb = new StringBuilder();
if (words[0].length() > 0) {
    sb.append(Character.toUpperCase(words[0].charAt(0)) + words[0].subSequence(1, words[0].length()).toString().toLowerCase());
    for (int i = 1; i < words.length; i++) {
        sb.append(" ");
        sb.append(Character.toUpperCase(words[i].charAt(0)) + words[i].subSequence(1, words[i].length()).toString().toLowerCase());
    }
}
String titleCaseValue = sb.toString();

...where input is an EditText view. It is also helpful to set the input type on the view so that it defaults to title case anyway:

input.setInputType(InputType.TYPE_TEXT_FLAG_CAP_WORDS);
Community
  • 1
  • 1
Russ
  • 3,768
  • 7
  • 28
  • 37
  • 2
    if you have possibly several spaces, you can use split("\\s+") (splits on 1 or more space) – njzk2 Sep 12 '12 at 12:10
13

this helps you

EditText view = (EditText) find..
String txt = view.getText();
txt = String.valueOf(txt.charAt(0)).toUpperCase() + txt.substring(1, txt.length());
Ankitkumar Makwana
  • 3,475
  • 3
  • 19
  • 45
9

In the XML, you can do it like this:

android:inputType="textCapWords"

Check the reference for other options, like Sentence case, all upper letters, etc. here:

http://developer.android.com/reference/android/widget/TextView.html#attr_android:inputType

zeeshan
  • 4,913
  • 1
  • 49
  • 58
6

Here is the WordUtils.capitalize() method in case you don't want to import the whole class.

public static String capitalize(String str) {
    return capitalize(str, null);
}

public static String capitalize(String str, char[] delimiters) {
    int delimLen = (delimiters == null ? -1 : delimiters.length);
    if (str == null || str.length() == 0 || delimLen == 0) {
        return str;
    }
    int strLen = str.length();
    StringBuffer buffer = new StringBuffer(strLen);
    boolean capitalizeNext = true;
    for (int i = 0; i < strLen; i++) {
        char ch = str.charAt(i);

        if (isDelimiter(ch, delimiters)) {
            buffer.append(ch);
            capitalizeNext = true;
        } else if (capitalizeNext) {
            buffer.append(Character.toTitleCase(ch));
            capitalizeNext = false;
        } else {
            buffer.append(ch);
        }
    }
    return buffer.toString();
}
private static boolean isDelimiter(char ch, char[] delimiters) {
    if (delimiters == null) {
        return Character.isWhitespace(ch);
    }
    for (int i = 0, isize = delimiters.length; i < isize; i++) {
        if (ch == delimiters[i]) {
            return true;
        }
    }
    return false;
}

Hope it helps.

Edit:

This code is taken from https://commons.apache.org/proper/commons-lang/apidocs/src-html/org/apache/commons/lang3/text/WordUtils.html

which has Apache 2.0 license.

@straya pointed out in the comments that people might copy this code directly into their projects without a valid license attribution and hence violate the copyright.

So, if you want use this code anywhere be sure to include proper license notice, including the one you can get from the above link and additional notice text stating you modified it.

SafaOrhan
  • 690
  • 9
  • 19
  • This code assumes the input string is all lower case. To handle all upper case input you need to tweak the following line... buffer.append(ch); becomes buffer.append(Character.toLowerCase(ch)); in the 3rd branch of the main else statement. – Andrew Kelly Sep 23 '14 at 00:16
  • Technically you breached copyright here by not adhering to the simple license attribution requirements. If this was a university assessment that would be plagiarism. Simply copy the license into the code or provide a link to it in your comment. – straya Sep 06 '21 at 02:51
  • @straya very well said, at the time I posted this answer, it seems I didn't know much about licensing. I will edit my answer now to give better attribution and a note for the readers to include licence attribution. Thanks for the heads up. – SafaOrhan Sep 06 '21 at 07:26
4

I just had the same problem and solved it with this:

import android.text.TextUtils;
...

String[] words = input.split("[.\\s]+");

for(int i = 0; i < words.length; i++) {
    words[i] = words[i].substring(0,1).toUpperCase()
               + words[i].substring(1).toLowerCase();
}

String titleCase = TextUtils.join(" ", words);

Note, in my case, I needed to remove periods, as well. Any characters that need to be replaced with spaces can be inserted between the square braces during the "split." For instance, the following would ultimately replace underscores, periods, commas or whitespace:

String[] words = input.split("[_.,\\s]+");

This, of course, can be accomplished much more simply with the "non-word character" symbol:

String[] words = input.split("\\W+");

It's worth mentioning that numbers and hyphens ARE considered "word characters" so this last version met my needs perfectly and hopefully will help someone else out there.

gMale
  • 17,147
  • 17
  • 91
  • 116
3

Just do something like this:

public static String toCamelCase(String s){
    if(s.length() == 0){
        return s;
    }
    String[] parts = s.split(" ");
    String camelCaseString = "";
    for (String part : parts){
        camelCaseString = camelCaseString + toProperCase(part) + " ";
    }
    return camelCaseString;
}

public static String toProperCase(String s) {
    return s.substring(0, 1).toUpperCase() +
            s.substring(1).toLowerCase();
}
mossman252
  • 462
  • 4
  • 3
1

Use this function to convert data in camel case

 public static String camelCase(String stringToConvert) {
        if (TextUtils.isEmpty(stringToConvert))
            {return "";}
        return Character.toUpperCase(stringToConvert.charAt(0)) +
                stringToConvert.substring(1).toLowerCase();
    }
Rajesh Tiwari
  • 410
  • 5
  • 22
1

Kotlin - Android - Title Case / Camel Case function

fun toTitleCase(str: String?): String? {

        if (str == null) {
            return null
        }

        var space = true
        val builder = StringBuilder(str)
        val len = builder.length

        for (i in 0 until len) {
            val c = builder[i]
            if (space) {
                if (!Character.isWhitespace(c)) {
                    // Convert to title case and switch out of whitespace mode.
                    builder.setCharAt(i, Character.toTitleCase(c))
                    space = false
                }
            } else if (Character.isWhitespace(c)) {
                space = true
            } else {
                builder.setCharAt(i, Character.toLowerCase(c))
            }
        }

        return builder.toString()
    }

OR

fun camelCase(stringToConvert: String): String {
    if (TextUtils.isEmpty(stringToConvert)) {
        return "";
    }
    return Character.toUpperCase(stringToConvert[0]) +
            stringToConvert.substring(1).toLowerCase();
}
Ramana V V K
  • 1,245
  • 15
  • 24
0

Please check the solution below it will work for both multiple string and also single string to

 String toBeCapped = "i want this sentence capitalized";  
 String[] tokens = toBeCapped.split("\\s"); 

 if(tokens.length>0)
 {
   toBeCapped = ""; 

    for(int i = 0; i < tokens.length; i++)
    { 
     char capLetter = Character.toUpperCase(tokens[i].charAt(0)); 
     toBeCapped += " " + capLetter + tokens[i].substring(1, tokens[i].length()); 
    }
 }
 else
 {
  char capLetter = Character.toUpperCase(toBeCapped.charAt(0)); 
  toBeCapped += " " + capLetter + toBeCapped .substring(1, toBeCapped .length()); 
 }
Ravindra Kushwaha
  • 7,846
  • 14
  • 53
  • 103
0

I simplified the accepted answer from @Russ such that there is no need to differentiate the first word in the string array from the rest of the words. (I add the space after every word, then just trim the sentence before returning the sentence)

public static String toCamelCaseSentence(String s) {

    if (s != null) {
        String[] words = s.split(" ");

        StringBuilder sb = new StringBuilder();

        for (int i = 0; i < words.length; i++) {
            sb.append(toCamelCaseWord(words[i]));
        }

        return sb.toString().trim();
    } else {
        return "";
    }
}

handles empty strings (multiple spaces in sentence) and single letter words in the String.

public static String toCamelCaseWord(String word) {
    if (word ==null){
        return "";
    }

    switch (word.length()) {
        case 0:
            return "";
        case 1:
            return word.toUpperCase(Locale.getDefault()) + " ";
        default:
            char firstLetter = Character.toUpperCase(word.charAt(0));
            return firstLetter + word.substring(1).toLowerCase(Locale.getDefault()) + " ";
    }
}
Angel Koh
  • 12,479
  • 7
  • 64
  • 91
0

I wrote a code based on Apache's WordUtils.capitalize() method. You can set your Delimiters as a Regex String. If you want words like "of" to be skipped, just set them as a delimiter.

public static String capitalize(String str, final String delimitersRegex) {
    if (str == null || str.length() == 0) {
        return "";
    }

    final Pattern delimPattern;
    if (delimitersRegex == null || delimitersRegex.length() == 0){
        delimPattern = Pattern.compile("\\W");
    }else {
        delimPattern = Pattern.compile(delimitersRegex);
    }

    final Matcher delimMatcher = delimPattern.matcher(str);
    boolean delimiterFound = delimMatcher.find();

    int delimeterStart = -1;
    if (delimiterFound){
        delimeterStart = delimMatcher.start();
    }

    final int strLen = str.length();
    final StringBuilder buffer = new StringBuilder(strLen);

    boolean capitalizeNext = true;
    for (int i = 0; i < strLen; i++) {
        if (delimiterFound && i == delimeterStart) {
            final int endIndex = delimMatcher.end();

            buffer.append( str.substring(i, endIndex) );
            i = endIndex;

            if( (delimiterFound = delimMatcher.find()) ){
                delimeterStart = delimMatcher.start();
            }

            capitalizeNext = true;
        } else {
            final char ch = str.charAt(i);

            if (capitalizeNext) {
                buffer.append(Character.toTitleCase(ch));
                capitalizeNext = false;
            } else {
                buffer.append(ch);
            }
        }
    }
    return buffer.toString();
}

Hope that Helps :)

ErickBergmann
  • 689
  • 5
  • 14
0

If you're looking for Title case format, This kotlin extension functions may help you.

fun String.toTitleCase(): String {
if (isNotEmpty()) {
    val charArray = this.toCharArray()
    return buildString {
        for (i: Int in charArray.indices) {
            val c = charArray[i]
            // start find space from 1 because it can cause invalid index of position if (-1)
            val previous = if (i > 0) charArray[(i - 1)] else null
            // true if before is space char
            val isBeforeSpace = previous?.let { Character.isSpaceChar(it) } ?: false
            // append char to uppercase if current index is 0 or before is space
            if (i == 0 || isBeforeSpace) append(c.toUpperCase()) else append(c)
            print("char:$c, \ncharIndex: $i, \nisBeforeSpace: $isBeforeSpace\n\n")
        }
        print("result: $this")
    }
} return this }

And implement like

data class User(val name :String){ val displayName: String get() = name.toTitleCase() }
0

In kotlin I made it easy like this

yoursString.lowercase().replaceFirstChar { it.uppercase() }

Raluca Lucaci
  • 2,058
  • 3
  • 20
  • 37
  • Nice (not sure that actually converts to title case though - ie. when there is more than one word?) - Kotlin did not exist when I asked this question! :D – Russ May 04 '23 at 16:20
0

In kotlin, you can do this like

val value = "hey this is test word" // or{HEY THIS IS TEST WORD}
value.lowercase()
value.replaceFirstChar {
   if (it.isLowerCase()) {
     it.titlecase(Locale.getDefault())
   } else {
     it.toString()
   }
}
println(value)
Anshul1507
  • 529
  • 6
  • 14