Existe um método para conversão de String para caixa de título?


99

Existe algum método integrado disponível para converter uma string no formato de caixa de título?


3
Todos que estão lendo esta pergunta: cuidado, pois muitas das respostas mais votadas aqui NÃO FUNCIONAM CORRETAMENTE em todos os idiomas. Você precisa de uma biblioteca com reconhecimento de i18n para obter um título correto, como ICU4J (consulte a resposta de Daniel F).
sffc

Respostas:


106

Apache Commons StringUtils.capitalize () ou Commons Text WordUtils.capitalize ()

por exemplo: WordUtils.capitalize("i am FINE") = "I Am FINE"do documento WordUtils


14
WordUtils.capitalizeFully () foi melhor para mim, pois oferece: WordUtils.capitalizeFully ("i am FINE") = "I Am Fine"
theINtoy

2
Apenas uma pequena atualização, o WordUtils foi para o Commons Text e está obsoleto dentro do Commons Lang
msrd0

A primavera também temStringUtils.capitalise()
OrangeDog

@OrangeDog, você quer dizer capitalize()?
TylerH

@TylerH sim, autocorreção
resolveu

60

Não há métodos capitalize () ou titleCase () na classe String do Java. Você tem duas opções:

 StringUtils.capitalize(null)  = null
 StringUtils.capitalize("")    = ""
 StringUtils.capitalize("cat") = "Cat"
 StringUtils.capitalize("cAt") = "CAt"
 StringUtils.capitalize("'cat'") = "'cat'"
  • escrever (ainda outro) método auxiliar estático toTitleCase ()

Implementação de amostra

public static String toTitleCase(String input) {
    StringBuilder titleCase = new StringBuilder(input.length());
    boolean nextTitleCase = true;

    for (char c : input.toCharArray()) {
        if (Character.isSpaceChar(c)) {
            nextTitleCase = true;
        } else if (nextTitleCase) {
            c = Character.toTitleCase(c);
            nextTitleCase = false;
        }

        titleCase.append(c);
    }

    return titleCase.toString();
}

Caso de teste

    System.out.println(toTitleCase("string"));
    System.out.println(toTitleCase("another string"));
    System.out.println(toTitleCase("YET ANOTHER STRING"));

saídas:

Corda
Outra corda
AINDA OUTRA STRING

1
Esta é uma pequena rotina agradável, mas falha no caso mais geral em que Strings podem representar nomes. Nesse caso, a capitalização também precisaria ocorrer após apóstrofos e hifens. Por exemplo. O'Connor e J. Wilkes-Booth. É claro que outros idiomas podem ter regras adicionais para maiúsculas e minúsculas.
scottb

... Se fosse incluir isso, não precisaria de uma pesquisa inteira no dicionário apenas para descobrir se a palavra atual era um nome? Isso parece um pouco demais para qualquer método.
MMJZ

Este código é quase bom porque alguns nomes podem ter preposições como de, del, della, dei, da como em Maria del Carmen, Maria da Silva, Maria della Salute, etc. coderanch.com/t/35096/Programming/…
Junior Mayhé

Isso não rompe com o apóstrofo? E O'Brian, por exemplo.
sproketboy

1
Nota: para evitar o redimensionamento do usado internamente char[]no StringBuildereu sugiro usarnew StringBuilder(input.length())
Lino

38

Se eu puder enviar minha opinião sobre a solução ...

O método a seguir é baseado naquele que dfa postou. Ele faz a seguinte alteração importante (que é adequada para a solução que eu precisava no momento): força todos os caracteres na string de entrada para minúsculas, a menos que seja imediatamente precedido por um "delimitador acionável", caso em que o caractere é forçado a maiúsculas.

Uma limitação importante da minha rotina é que ela pressupõe que "maiúsculas e minúsculas" é uniformemente definida para todos os locais e é representada pelas mesmas convenções de maiúsculas e minúsculas que usei e, portanto, é menos útil do que o código do dfa nesse aspecto.

public static String toDisplayCase(String s) {

    final String ACTIONABLE_DELIMITERS = " '-/"; // these cause the character following
                                                 // to be capitalized
    
    StringBuilder sb = new StringBuilder();
    boolean capNext = true;

    for (char c : s.toCharArray()) {
        c = (capNext)
                ? Character.toUpperCase(c)
                : Character.toLowerCase(c);
        sb.append(c);
        capNext = (ACTIONABLE_DELIMITERS.indexOf((int) c) >= 0); // explicit cast not needed
    }
    return sb.toString();
}

VALORES DE TESTE

uma linha

maRTin o'maLLEY

john wilkes-booth

AINDA OUTRA STRING

SAÍDAS

Uma linha

Martin O'Malley

John Wilkes-Booth

Mais uma corda


não funcionará com ligaduras como lj, cujas maiúsculas são LJ, mas titlecase é Lj. Use em seu Character.toTitleCaselugar.
mihi de

@mihi: também não funcionará com outras regras especializadas, por exemplo. sobrenomes como McNamara ou MacDonald.
scottb

mas esses casos não podem ser corrigidos inerentemente. Usando a função correta de conversão de maiúsculas e minúsculas (titlecase deve ser usado para capitalizar uma palavra, e não maiúsculas, de acordo com as regras do Unicode) pode ser feito (e é fácil).
mihi

Isso não faria (não) também faria com que "dela" se tornasse "dela"?
allicarn

É verdade. Isso funciona bem em campos de nome, mas, como você observou, não em prosa geral. Nem funcionaria bem com todos os nomes, vulcanos em particular (T'Pau em vez de T'pau).
scottb


10

Você pode usar as linguagens do apache commons assim:

WordUtils.capitalizeFully("this is a text to be capitalize")

você pode encontrar o documento java aqui: WordUtils.capitalizeFully java doc

e se você quiser remover os espaços entre os mundos, você pode usar:

StringUtils.remove(WordUtils.capitalizeFully("this is a text to be capitalize")," ")

você pode encontrar o documento java para String StringUtils.remove java doc

Espero que esta ajuda.



3

Aqui está outra tomada com base nas respostas de @dfa e @scottb que lida com qualquer caractere diferente de letra / dígito:

public final class TitleCase {

    public static String toTitleCase(String input) {

        StringBuilder titleCase = new StringBuilder(input.length());
        boolean nextTitleCase = true;

        for (char c : input.toLowerCase().toCharArray()) {
            if (!Character.isLetterOrDigit(c)) {
                nextTitleCase = true;
            } else if (nextTitleCase) {
                c = Character.toTitleCase(c);
                nextTitleCase = false;
            }
            titleCase.append(c);
        }

        return titleCase.toString();
    }

}

Entrada fornecida:

MARY ÄNN O'CONNEŽ-ŠUSLIK

a saída é

Mary Änn O'Connež-Šuslik


2

Isso é algo que eu escrevi para converter snake_case em lowerCamelCase, mas poderia ser facilmente ajustado com base nos requisitos

private String convertToLowerCamel(String startingText)
{
    String[] parts = startingText.split("_");
    return parts[0].toLowerCase() + Arrays.stream(parts)
                    .skip(1)
                    .map(part -> part.substring(0, 1).toUpperCase() + part.substring(1).toLowerCase())
                    .collect(Collectors.joining());
}

Sua resposta funciona perfeitamente, no entanto, a solução não parece lidar com uma sequência de palavras simples, talvez uma condição se deva ser suficiente.
yashgarg1232

1

Eu sei que este é mais antigo, mas não tem a resposta simples, eu precisava desse método para minha codificação, então adicionei aqui, simples de usar.

public static String toTitleCase(String input) {
    input = input.toLowerCase();
    char c =  input.charAt(0);
    String s = new String("" + c);
    String f = s.toUpperCase();
    return f + input.substring(1);
}

1

Eu tive esse problema e eu procurei por ele, então eu fiz meu próprio método usando algumas palavras-chave java só preciso passar a variável String como parâmetro e obter a saída como String com o título adequado.

public class Main
{
  public static void main (String[]args)
  {
    String st = "pARVeEN sISHOsIYA";
    String mainn = getTitleCase (st);
      System.out.println (mainn);
  }


  public static String getTitleCase(String input)
  {
    StringBuilder titleCase = new StringBuilder (input.length());
    boolean hadSpace = false;
    for (char c:input.toCharArray ()){
        if(Character.isSpaceChar(c)){
            hadSpace = true;
            titleCase.append (c);
            continue;
        }
        if(hadSpace){
            hadSpace = false;
            c = Character.toUpperCase(c);
            titleCase.append (c);
        }else{
            c = Character.toLowerCase(c);
            titleCase.append (c);
        }
    }
    String temp=titleCase.toString ();
    StringBuilder titleCase1 = new StringBuilder (temp.length ());
    int num=1;
    for (char c:temp.toCharArray ())
        {   if(num==1)
            c = Character.toUpperCase(c);
            titleCase1.append (c);
            num=0;
        }
        return titleCase1.toString ();
    }
}

Aqui, eu não usei o método de corte em nenhum lugar porque no meu caso eu estava obtendo a corda aparada de maneira adequada.
Parveen Sishodiya 01 de

0

você pode muito bem usar

org.apache.commons.lang.WordUtils

ou

CaseFormat

da API do Google.


1
Seria útil adicionar o método e um exemplo.
jechaviz

CaseFormat só tem formatos tipicamente usados ​​em identificadores de programa (UpperCamel, lower-hypen, UPPER_UNDERSCORE, etc.) e só suporta texto ASCII. Não funcionaria bem para converter para caixa de título.
M. Justin

0

Recentemente também tive esse problema e infelizmente tive muitas ocorrências de nomes começando com Mc e Mac, acabei usando uma versão do código de scottb que mudei para lidar com esses prefixos, então está aqui caso alguém queira usá-lo.

Ainda há casos extremos em que isso não ocorre, mas a pior coisa que pode acontecer é que uma letra estará em minúscula quando deveria ser maiúscula.

/**
 * Get a nicely formatted representation of the name. 
 * Don't send this the whole name at once, instead send it the components.<br>
 * For example: andrew macnamara would be returned as:<br>
 * Andrew Macnamara if processed as a single string<br>
 * Andrew MacNamara if processed as 2 strings.
 * @param name
 * @return correctly formatted name
 */
public static String getNameTitleCase (String name) {
    final String ACTIONABLE_DELIMITERS = " '-/";
    StringBuilder sb = new StringBuilder();
    if (name !=null && !name.isEmpty()){                
        boolean capitaliseNext = true;
        for (char c : name.toCharArray()) {
            c = (capitaliseNext)?Character.toUpperCase(c):Character.toLowerCase(c);
            sb.append(c);
            capitaliseNext = (ACTIONABLE_DELIMITERS.indexOf((int) c) >= 0);
        }                       
        name = sb.toString();    
        if (name.startsWith("Mc") && name.length() > 2 ) {
            char c = name.charAt(2);
            if (ACTIONABLE_DELIMITERS.indexOf((int) c) < 0) {
                sb = new StringBuilder();
                sb.append (name.substring(0,2));
                sb.append (name.substring(2,3).toUpperCase());
                sb.append (name.substring(3));
                name=sb.toString();
            }               
        } else if (name.startsWith("Mac") && name.length() > 3) {
            char c = name.charAt(3);
            if (ACTIONABLE_DELIMITERS.indexOf((int) c) < 0) {
                sb = new StringBuilder();
                sb.append (name.substring(0,3));
                sb.append (name.substring(3,4).toUpperCase());
                sb.append (name.substring(4));
                name=sb.toString();
            }
        }
    }
    return name;    
}

0

Conversão para caixa de título adequada:

String s= "ThiS iS SomE Text";
String[] arr = s.split(" ");
s = "";
for (String s1 : arr) {
    s += WordUtils.capitalize(s1.toLowerCase()) + " ";
}
s = s.substring(0, s.length() - 1);

Resultado: "Este é algum texto"


0

Usando o Spring StringUtils:

org.springframework.util.StringUtils.capitalize(someText);

Se você já está usando o Spring, isso evita trazer outro framework.


0

Use este método para converter uma string para maiúsculas e minúsculas:

static String toTitleCase(String word) {
    return Stream.of(word.split(" "))
            .map(w -> w.toUpperCase().charAt(0)+ w.toLowerCase().substring(1))
            .reduce((s, s2) -> s + " " + s2).orElse("");
}

0

Este conversor transforma qualquer string contendo caixa de camelo, espaços em branco, dígitos e outros caracteres para caixa de título limpa.

/**
 * Convert a string to title case in java (with tests).
 *
 * @author Sudipto Chandra
 */
public abstract class TitleCase {

    /**
     * Returns the character type. <br>
     * <br>
     * Digit = 2 <br>
     * Lower case alphabet = 0 <br>
     * Uppercase case alphabet = 1 <br>
     * All else = -1.
     *
     * @param ch
     * @return
     */
    private static int getCharType(char ch) {
        if (Character.isLowerCase(ch)) {
            return 0;
        } else if (Character.isUpperCase(ch)) {
            return 1;
        } else if (Character.isDigit(ch)) {
            return 2;
        }
        return -1;
    }

    /**
     * Converts any given string in camel or snake case to title case.
     * <br>
     * It uses the method getCharType and ignore any character that falls in
     * negative character type category. It separates two alphabets of not-equal
     * cases with a space. It accepts numbers and append it to the currently
     * running group, and puts a space at the end.
     * <br>
     * If the result is empty after the operations, original string is returned.
     *
     * @param text the text to be converted.
     * @return a title cased string
     */
    public static String titleCase(String text) {
        if (text == null || text.length() == 0) {
            return text;
        }

        char[] str = text.toCharArray();
        StringBuilder sb = new StringBuilder();

        boolean capRepeated = false;
        for (int i = 0, prev = -1, next; i < str.length; ++i, prev = next) {
            next = getCharType(str[i]);
            // trace consecutive capital cases
            if (prev == 1 && next == 1) {
                capRepeated = true;
            } else if (next != 0) {
                capRepeated = false;
            }
            // next is ignorable
            if (next == -1) {
                // System.out.printf("case 0, %d %d %s\n", prev, next, sb.toString());
                continue; // does not append anything
            }
            // prev and next are of same type
            if (prev == next) {
                sb.append(str[i]);
                // System.out.printf("case 1, %d %d %s\n", prev, next, sb.toString());
                continue;
            }
            // next is not an alphabet
            if (next == 2) {
                sb.append(str[i]);
                // System.out.printf("case 2, %d %d %s\n", prev, next, sb.toString());
                continue;
            }
            // next is an alphabet, prev was not +
            // next is uppercase and prev was lowercase
            if (prev == -1 || prev == 2 || prev == 0) {
                if (sb.length() != 0) {
                    sb.append(' ');
                }
                sb.append(Character.toUpperCase(str[i]));
                // System.out.printf("case 3, %d %d %s\n", prev, next, sb.toString());
                continue;
            }
            // next is lowercase and prev was uppercase
            if (prev == 1) {
                if (capRepeated) {
                    sb.insert(sb.length() - 1, ' ');
                    capRepeated = false;
                }
                sb.append(str[i]);
                // System.out.printf("case 4, %d %d %s\n", prev, next, sb.toString());
            }
        }
        String output = sb.toString().trim();
        output = (output.length() == 0) ? text : output;
        //return output;

        // Capitalize all words (Optional)
        String[] result = output.split(" ");
        for (int i = 0; i < result.length; ++i) {
            result[i] = result[i].charAt(0) + result[i].substring(1).toLowerCase();
        }
        output = String.join(" ", result);
        return output;
    }

    /**
     * Test method for the titleCase() function.
     */
    public static void testTitleCase() {
        System.out.println("--------------- Title Case Tests --------------------");
        String[][] samples = {
            {null, null},
            {"", ""},
            {"a", "A"},
            {"aa", "Aa"},
            {"aaa", "Aaa"},
            {"aC", "A C"},
            {"AC", "Ac"},
            {"aCa", "A Ca"},
            {"ACa", "A Ca"},
            {"aCamel", "A Camel"},
            {"anCamel", "An Camel"},
            {"CamelCase", "Camel Case"},
            {"camelCase", "Camel Case"},
            {"snake_case", "Snake Case"},
            {"toCamelCaseString", "To Camel Case String"},
            {"toCAMELCase", "To Camel Case"},
            {"_under_the_scoreCamelWith_", "Under The Score Camel With"},
            {"ABDTest", "Abd Test"},
            {"title123Case", "Title123 Case"},
            {"expect11", "Expect11"},
            {"all0verMe3", "All0 Ver Me3"},
            {"___", "___"},
            {"__a__", "A"},
            {"_A_b_c____aa", "A B C Aa"},
            {"_get$It132done", "Get It132 Done"},
            {"_122_", "122"},
            {"_no112", "No112"},
            {"Case-13title", "Case13 Title"},
            {"-no-allow-", "No Allow"},
            {"_paren-_-allow--not!", "Paren Allow Not"},
            {"Other.Allow.--False?", "Other Allow False"},
            {"$39$ldl%LK3$lk_389$klnsl-32489  3 42034 ", "39 Ldl Lk3 Lk389 Klnsl32489342034"},
            {"tHis will BE MY EXAMple", "T His Will Be My Exa Mple"},
            {"stripEvery.damn-paren- -_now", "Strip Every Damn Paren Now"},
            {"getMe", "Get Me"},
            {"whatSthePoint", "What Sthe Point"},
            {"n0pe_aLoud", "N0 Pe A Loud"},
            {"canHave SpacesThere", "Can Have Spaces There"},
            {"  why_underScore exists  ", "Why Under Score Exists"},
            {"small-to-be-seen", "Small To Be Seen"},
            {"toCAMELCase", "To Camel Case"},
            {"_under_the_scoreCamelWith_", "Under The Score Camel With"},
            {"last one onTheList", "Last One On The List"}
        };
        int pass = 0;
        for (String[] inp : samples) {
            String out = titleCase(inp[0]);
            //String out = WordUtils.capitalizeFully(inp[0]);
            System.out.printf("TEST '%s'\nWANTS '%s'\nFOUND '%s'\n", inp[0], inp[1], out);
            boolean passed = (out == null ? inp[1] == null : out.equals(inp[1]));
            pass += passed ? 1 : 0;
            System.out.println(passed ? "-- PASS --" : "!! FAIL !!");
            System.out.println();
        }
        System.out.printf("\n%d Passed, %d Failed.\n", pass, samples.length - pass);
    }

    public static void main(String[] args) {
        // run tests
        testTitleCase();
    }
}

Aqui estão algumas entradas:

aCamel
TitleCase
snake_case
fromCamelCASEString
ABCTest
expect11
_paren-_-allow--not!
  why_underScore   exists  
last one onTheList 

E minhas saídas:

A Camel
Title Case
Snake Case
From Camel Case String
Abc Test
Expect11
Paren Allow Not
Why Under Score Exists
Last One On The List

0

Parece que nenhuma das respostas o formatou na caixa do título real: "Como conseguir o emprego dos seus sonhos", "Para matar um pássaro Mockingbird", etc., então fiz meu próprio método. Funciona melhor para textos em inglês.

private final static Set<Character> TITLE_CASE_DELIMITERS = new HashSet<>();

  static {
    TITLE_CASE_DELIMITERS.add(' ');
    TITLE_CASE_DELIMITERS.add('.');
    TITLE_CASE_DELIMITERS.add(',');
    TITLE_CASE_DELIMITERS.add(';');
    TITLE_CASE_DELIMITERS.add('/');
    TITLE_CASE_DELIMITERS.add('-');
    TITLE_CASE_DELIMITERS.add('(');
    TITLE_CASE_DELIMITERS.add(')');
  }

  private final static Set<String> TITLE_SMALLCASED_WORDS = new HashSet<>();

  static {
    TITLE_SMALLCASED_WORDS.add("a");
    TITLE_SMALLCASED_WORDS.add("an");
    TITLE_SMALLCASED_WORDS.add("the");
    TITLE_SMALLCASED_WORDS.add("for");
    TITLE_SMALLCASED_WORDS.add("in");
    TITLE_SMALLCASED_WORDS.add("on");
    TITLE_SMALLCASED_WORDS.add("of");
    TITLE_SMALLCASED_WORDS.add("and");
    TITLE_SMALLCASED_WORDS.add("but");
    TITLE_SMALLCASED_WORDS.add("or");
    TITLE_SMALLCASED_WORDS.add("nor");
    TITLE_SMALLCASED_WORDS.add("to");
  }

  public static String toCapitalizedWord(String oneWord) {
    if (oneWord.length() < 1) {
      return oneWord.toUpperCase();
    }
    return "" + Character.toTitleCase(oneWord.charAt(0)) + oneWord.substring(1).toLowerCase();
  }

  public static String toTitledWord(String oneWord) {
    if (TITLE_SMALLCASED_WORDS.contains(oneWord.toLowerCase())) {
      return oneWord.toLowerCase();
    }
    return toCapitalizedWord(oneWord);
  }

  public static String toTitleCase(String str) {
    StringBuilder result = new StringBuilder();
    StringBuilder oneWord = new StringBuilder();

    char previousDelimiter = 'x';
    /* on start, always move to upper case */
    for (char c : str.toCharArray()) {
      if (TITLE_CASE_DELIMITERS.contains(c)) {
        if (previousDelimiter == '-' || previousDelimiter == 'x') {
          result.append(toCapitalizedWord(oneWord.toString()));
        } else {
          result.append(toTitledWord(oneWord.toString()));
        }
        oneWord.setLength(0);
        result.append(c);
        previousDelimiter = c;
      } else {
        oneWord.append(c);
      }
    }
    if (previousDelimiter == '-' || previousDelimiter == 'x') {
      result.append(toCapitalizedWord(oneWord.toString()));
    } else {
      result.append(toTitledWord(oneWord.toString()));
    }
    return result.toString();
  }

  public static void main(String[] args) {
    System.out.println(toTitleCase("one year in paris"));
    System.out.println(toTitleCase("How to Land Your Dream Job"));
  }

0

Esta é a solução mais simples

    static void title(String a,String b){
    String ra = Character.toString(Character.toUpperCase(a.charAt(0)));
    String rb = Character.toString(Character.toUpperCase(b.charAt(0)));
    for(int i=1;i<a.length();i++){
        ra+=a.charAt(i);
    }
    for(int i=1;i<b.length();i++){
        rb+=b.charAt(i);
    }
    System.out.println(ra+" "+rb);

-1

Isso deve funcionar:

String str="i like pancakes";
String arr[]=str.split(" ");
String strNew="";
for(String str1:arr)
{
    Character oldchar=str1.charAt(0);
    Character newchar=Character.toUpperCase(str1.charAt(0));
    strNew=strNew+str1.replace(oldchar,newchar)+" ";    
}
System.out.println(strNew);

1
Esta não é uma resposta válida como o OP pediu builtin função. Veja também o comentário que aborda a complexidade oculta por trás disso, ou seja, i18n.
Marcus

-2

A maneira mais simples de converter qualquer string em uma caixa de título é usar o pacote googles org.apache.commons.lang.WordUtils

System.out.println(WordUtils.capitalizeFully("tHis will BE MY EXAMple"));

Resultará isso

Este será meu exemplo

Não sei por que é chamado de "capitalizeFully", onde na verdade a função não está fazendo um resultado de capital completo, mas de qualquer forma, essa é a ferramenta de que precisamos.


1
É nomeado capitalizeFullyporque coloca todas as palavras em maiúscula, incluindo aquelas que deveriam estar em minúsculas em um título. grammar.about.com/od/tz/g/Title-Case.htm
aij

2
Apache Commons não é propriedade do Google. É mantido pela Apache Software Foundation. commons.apache.org
ATutorMe

-3

Desculpe, eu sou um iniciante, então meu hábito de programar é uma droga!

public class TitleCase {

    String title(String sent)
    {   
        sent =sent.trim();
        sent = sent.toLowerCase();
        String[] str1=new String[sent.length()];
        for(int k=0;k<=str1.length-1;k++){
            str1[k]=sent.charAt(k)+"";
    }

        for(int i=0;i<=sent.length()-1;i++){
            if(i==0){
                String s= sent.charAt(i)+"";
                str1[i]=s.toUpperCase();
                }
            if(str1[i].equals(" ")){
                String s= sent.charAt(i+1)+"";
                str1[i+1]=s.toUpperCase();
                }

            System.out.print(str1[i]);
            }

        return "";
        }

    public static void main(String[] args) {
        TitleCase a = new TitleCase();
        System.out.println(a.title("   enter your Statement!"));
    }
}
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.