有没有一种将字符串转换为标题格式的方法?

126
有没有内置的方法可以将一个字符串转换为标题格式?

7
阅读此问题的每个人:请注意这里得票最高的许多答案并不适用于所有语言。您需要一个具有i18n意识的库进行正确的标题大小写转换,比如ICU4J(请参见Daniel F的答案)。 - sffc
这个回答解决了你的问题吗?如何将字符串中每个单词的首字母大写 - M. Justin
我撤回我的重复问题。这个问题特意不使用标题大小写,即保留每个单词非首字母的大小写,而不是将它们改为大写。例如,aBcD -> "ABcD",而不是"Abcd"。 - M. Justin
22个回答

1

我知道这是一个较旧的问题,但并没有简单的答案。我需要这个方法来编程,所以我在这里添加了它,使用起来很简单。

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

似乎没有一个答案格式符合实际的标题大小写规则: "如何找到梦想工作","杀死一只知更鸟"等等,所以我自己制定了一种方法。该方法最适用于英语文本。

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"));
  }

1
您可以很好地使用

org.apache.commons.lang.WordUtils

来自Google API的CaseFormat。

1
添加该方法及其示例将非常有用。 - jechaviz
CaseFormat 只包含通常用于程序标识符的格式(UpperCamel、lower-hypen、UPPER_UNDERSCORE 等),并且仅支持 ASCII 文本。它不适用于转换为标题大小写。 - M. Justin

1
这是最简单的解决方案。
    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
我曾遇到这个问题并进行了搜索,最后使用一些Java关键字自己编写了一个方法。只需要将字符串变量作为参数传递,即可得到格式正确的标题字符串输出。
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 ();
    }
}

在我的情况下,我得到了正确修剪的字符串,因此我没有在任何地方使用trim方法。 - Parveen Sishodiya

0

将文本转换为正确的标题格式:

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);

结果: "这是一些文本"


0

这个转换器将任何包含驼峰式、空格、数字和其他字符的字符串转换为经过清理的标题格式。

/**
 * 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();
    }
}

以下是一些输入:

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

我的输出:

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

我最近也遇到了这个问题,不幸的是,我的名字中有很多以Mc和Mac开头的情况。最终,我使用了scottb代码的一个版本,并对其进行了更改以处理这些前缀,因此在这里提供给任何想要使用它的人。

虽然这种方法仍然存在一些边缘情况,但最糟糕的情况就是某个字母应该大写而变成了小写。

/**
 * 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

不依赖 -

 public static String capitalizeFirstLetter(String s) {
    if(s.trim().length()>0){
        return s.substring(0, 1).toUpperCase() + s.substring(1);
    }
    return s;
}

public static String createTitleCase(String s) {
    if(s.trim().length()>0){
        final StringBuilder sb =  new StringBuilder();
        String[] strArr = s.split("\\s");
        for(int t =0; t < strArr.length; t++) {
            sb.append(capitalizeFirstLetter(strArr[t]));
            if(t != strArr.length-1) {
                sb.append(" ");
            }
        }

        s = sb.toString();

        sb.setLength(0);
    }
    return s;
}

这会丢弃所有空格,将其转换为UpperCamelCase,而不是Title Case。 - M. Justin
是的,只需在拆分字符串时删除*并在单词之间添加空格。 - Thangaraj
您最新更新的版本修复了UpperCamelCase问题。只要您可以将所有空格规范化为一个空格,它就工作正常。如果需要保留确切的间距(例如," "应保持为" "而不是变成" ",或者\n应保留为换行符而不是转换为空格),那么该解决方案不能原样使用,需要进行修改。 - M. Justin
是的,回复太长了,应该在传递值之前进行验证,这是开发人员的工作。空格也是一个字符串,我们不能限制应用程序/使用。这就是为什么内置方法能满足其需求。因此,如果你想在那里做自己的事情,可以的 :) - Thangaraj
是的,回复太长了,应该在传递值之前进行验证,这是开发人员的工作。空格也是一个字符串,我们不能限制应用程序/使用。这就是为什么内置方法适用于它的需求。因此,如果你想在那里做你的事情,你可以 :) - undefined
很抱歉,我看错了以为这是根据连续的空格来分割(例如 \\s+),而不是单个空格 \\s。尽管它仍然会规范化空白,这可能是想要的(例如 abc\tde\tf -> Abc De F 而不是 Abc\tDe\tF). - M. Justin

-1

这应该可以工作:

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
这不是一个有效的答案,因为OP要求使用内置函数。另外请注意评论中提到的隐藏复杂性,即i18n。 - Marcus

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接