web-dev-qa-db-ja.com

タイトルケースへの文字列変換

文字列をタイトルケース形式に変換するために利用可能な組み込みメソッドはありますか?

92
Raji

Apache Commons StringUtils.capitalize() または WordUtils.capitalize()

例:WordUtils.capitalize("i am FINE") = "I Am FINE" from WordUtils doc

98
aberrant80

stringクラスにはcapitalize()またはtitleCase()メソッドはありません。次の2つの選択肢があります。

 StringUtils.capitalize(null)  = null
 StringUtils.capitalize("")    = ""
 StringUtils.capitalize("cat") = "Cat"
 StringUtils.capitalize("cAt") = "CAt"
 StringUtils.capitalize("'cat'") = "'cat'"
  • (まだ別の)静的ヘルパーメソッドtoTitleCase()を記述する

サンプル実装

public static String toTitleCase(String input) {
    StringBuilder titleCase = new StringBuilder(input.lenght());
    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();
}

テストケース

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

出力:

文字列
別の文字列
まだ別の文字列
58
dfa

ソリューションに関する意見を提出する場合...

次の方法は、dfaが投稿した方法に基づいています。次の大きな変更を行います(これは当時必要だったソリューションに適しています)。入力文字列のすべての文字を強制的に小文字にします。ただし、「アクション可能な区切り文字」がすぐ前にある場合を除きます。大文字。

私のルーチンの主な制限は、「タイトルケース」がすべてのロケールに対して一律に定義され、使用した同じケース規則で表されることを前提としているため、その点でdfaのコードよりも役に立たないことです。

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

テスト値

文字列

マーティン・オマリー

ジョン・ウィルクス・ブース

まだ別の文字列

[〜#〜] outputs [〜#〜]

文字列

マーティン・オマリー

ジョン・ウィルクス・ブース

もう一つのひも

35
scottb

Apache Commonsの WordUtils.capitalizeFully() を使用します。

WordUtils.capitalizeFully(null)        = null
WordUtils.capitalizeFully("")          = ""
WordUtils.capitalizeFully("i am FINE") = "I Am Fine"
19
jiehanzheng

Apache commons langsは次のように使用できます。

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

ここでJava docを見つけることができます: WordUtils.capitalizeFully Java doc

そして、あなたが使用できる世界の間のスペースを削除したい場合:

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

Java Stringのドキュメント StringUtils.remove Java doc

この助けを願っています。

10
Vegegoku

最新のUnicode標準に従って正しい答えが必要な場合は、icu4jを使用する必要があります。

UCharacter.toTitleCase(Locale.US, "hello world", null, 0);

これはロケールに依存することに注意してください。

Apiドキュメント

実装

5
Daniel F

これは、snake_caseをlowerCamelCaseに変換するために書いたものですが、要件に基づいて簡単に調整できます。

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());
}
2
user1743960

以下は、文字/数字以外の文字を処理する@dfaと@scottbの回答に基づいた別の例です。

public final class TitleCase {

    public static String toTitleCase(String input) {

        StringBuilder titleCase = new StringBuilder();
        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();
    }

}

与えられた入力:

メアリー・アン・オコネシュシュリック

出力は

メアリー・アン・オコネジュ・シュスリク

2
mrts

このメソッドを使用して、文字列をタイトルケースに変換します。

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

SpringのStringUtilsを使用する:

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

とにかく既にSpringを使用している場合は、別のフレームワークを持ち込むことを避けます。

0
David Lavender

あなたは非常にうまく使うことができます

org.Apache.commons.lang.WordUtils

または

CaseFormat

googleのAPIから。

0
opensourcegeek

キャメルケース、空白、数字、その他の文字を含む文字列を変換するために、タイトルケースコンバーターが必要でした。しかし、利用可能なソリューションはどれも機能しませんでした。最後に、私は自分用にそれを構築しました。

/*
 * Copyright (C) 2018 Sudipto Chandra
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
/**
 * 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
Dipu

私も最近この問題に遭遇しましたが、残念ながらMcとMacで始まる名前の多くが発生しました。結局、これらのプレフィックスを処理するように変更したscottbのコードのバージョンを使用することになりました。

これが見落とすEdgeケースはまだありますが、最悪の事態は、大文字にする必要がある場合に小文字になることです。

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

適切なタイトルケースへの変換:

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
VAIBHAV SHEERSH