web-dev-qa-db-ja.com

JavaのtoLowerCase()およびtoUpperCase()でロケールを使用する

Javaで文字列のすべての文字を大文字または小文字に変換するコードが必要でした。

私は次のような方法を見つけました:

public static String changelowertoupper()
{
         String str = "CyBeRdRaGoN";
         str=str.toLowerCase(Locale.ENGLISH);
         return str;
}

トルコ語のような特定のLocalesを使用して、「i(ドットなし)代わりにi(ドット付き)。 "

UK、US、ENGLISHなどのLocalesを使用しても安全ですか?文字列に適用した場合、それらの間に大きな違いはありますか?

Localesで最も好ましいStringはどれですか?

59
Arjun K P

ロケールを使用する必要があると思います

たとえば、トルコ語ロケールの「TITLE」.toLowerCase()は「tıtle」を返します。「ı」はローマ字小文字DOTLESS I文字です。ロケールに依存しない文字列の正しい結果を取得するには、toLowerCase(Locale.ENGLISH)を使用します。

私はこれらのリンクをあなたの問題の解決策と呼んでおり、あなたの状況「トルコ語」に留意する必要があります

**FROM THE LINKS**

toLowerCase()は国際化(i18n)を尊重します。ロケールに関して大文字と小文字の変換を実行します。 toLowerCase()を呼び出すと、内部的にtoLowerCase(Locale.getDefault())が呼び出されます。ロケールに依存するため、ロケールを独立して解釈するロジックを記述しないでください。

import Java.util.Locale;

public class ToLocaleTest {
    public static void main(String[] args) throws Exception {
        Locale.setDefault(new Locale("lt")); //setting Lithuanian as locale
        String str = "\u00cc";
    System.out.println("Before case conversion is "+str+
" and length is "+str.length());// Ì
        String lowerCaseStr = str.toLowerCase();
    System.out.println("Lower case is "+lowerCaseStr+
" and length is "+lowerCaseStr.length());// iı`
    }
}

上記のプログラムでは、変換前後の文字列の長さを確認します。 1と3になります。はい。大文字と小文字の変換前後の文字列の長さは異なります。このシナリオで文字列の長さに依存している場合、ロジックはトスになります。プログラムが異なる環境で実行されると、失敗する場合があります。これは、コードレビューの良いキャッチになります。

より安全にするために、別のメソッドtoLowerCase(Locale.English)を使用し、ロケールを常に英語にオーバーライドすることができます。しかし、あなたは国際化されていません。

重要なのは、toLowerCase()がロケール固有であるということです。

参照1
参照2
参照


Dotless-iは、ドットなしの小文字の「i」です。この文字の大文字は、通常の「I」です。別の文字「ドット付きI」があります。この文字の小文字は、通常の小文字「i」です。

問題に気づきましたか?この非対称な変換は、プログラミングで深刻な問題を引き起こします。 toLowerCaseおよびtoUpperCase関数の実装が(IMHO)不十分であるため、主にJavaアプリケーションでこの問題に直面しています。

Javaでは、String.toLowerCase()メソッドはデフォルトのロケールに従って文字を小文字に変換します。これは、アプリケーションがトルコ語ロケールで動作する場合、特に特定の文字セットに従う必要があるファイル名またはURLに対してこの関数を使用している場合に問題を引き起こします。

以前に2つの深刻な例についてブログに書いたことがあります。名前に「i」が含まれるスクリプトライブラリのコンパイルエラーと、XPageが名前に「I」が含まれるデータベースにある場合のXSPマネージャーのエラーです。

私が言ったように、長い歴史があります。たとえば、一部のR7バージョンでは、名前が「I」で始まる場合、ルーターは受信者にメッセージを送信できませんでした。メッセージレポートエージェントは、R8までトルコ語ロケールで実行されていませんでした。トルコ語ロケールのユーザーは誰でもLotus Notes 8.5.1をインストールできませんでした(実際です!)。リストは続きます...

トルコにはベータテスターがほとんどなく、顧客はこれらの問題に対してPMRを開きません。したがって、これらの問題は開発チームにとって最優先事項ではありません。

Javaチームは最新のドキュメントに特別な警告を追加しました:

このメソッドはロケールに依存するため、ロケールを個別に解釈することを目的とした文字列に使用すると、予期しない結果が生じる場合があります。例としては、プログラミング言語識別子、プロトコルキー、HTMLタグなどがあります。たとえば、トルコ語ロケールの「TITLE」.toLowerCase()は「tıtle」を返します。「ı」はローマ字小文字DOTLESS I文字です。ロケールに依存しない文字列の正しい結果を取得するには、toLowerCase(Locale.ENGLISH)を使用します。

リンクを読んでくださいPOSTすべての「このISコメントに返信]

64
shareef

Stringの言語に適したロケールを作成できます。

例えば:

toUpperCase(new Locale("tr","TR"));

トルコ語のトリックを行います。

7
Caner
String str = "CyBeRdRaGoN";

str = str.toLowerCase(); // str = "cyberdragon"

str = str.toUpperCase(); // str = "CYBERDRAGON"

アプリケーションはデフォルトのロケールを選択するため、トルコ語ロケールでトルコ語でアプリケーションを実行すると、ドットなしのiが表示されます

6
alaster

文字列のチェックにこの関数を使用している場合(例:検索)小文字または大文字の形式の文字列を使用してチェックしても安全です。次のように使用できます。

if (mViewData.list.data[i].Name.toLowerCase(new Locale("tr", "TR"))
   .contains(mViewHolder.tctSearch.getText().toString().trim()
                                      .toLowerCase(new Locale("tr", "TR")))) {
    // your code here...
}

私は同じ問題に直面していますが、リストビューでの検索の場合です。同じ問題を抱えている人を助けるかもしれないというこの答えを追加しました。

1
Alp Altunel

コトリンで

private fun changelowertoupper(): String {
        val str = "CyBeRdRaGoN"
        return str.toLowerCase(Locale.ROOT) // or Locale.getDefault()
    }
0
Irvin Joao