1. ホーム
  2. java

[解決済み] Java の toLowerCase() と toUpperCase() を使ったロケールの使用法

2023-06-05 01:20:53

質問

Javaで文字列中の全ての文字を大文字・小文字に変換するコードが欲しいのですが、どのようにすればよいですか?

次のようなメソッドを見つけました。

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

今、私は、特定の Locale を使うと、トルコ語のように i (ドットなし) の代わりに i (ドット付き) ."

を使っても大丈夫でしょうか? Locale を使っても大丈夫ですか?文字列に適用した場合、それらの間に大きな違いがあるのでしょうか?

最も好ましいのは Locale に対して String s?

どのように解決するのですか?

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

例えば、トルコ語のロケールで "TITLE".toLowerCase() を実行すると、次のようになります。 ここで、'ı'はLATIN SMALL LETTER DOTLESS I文字です。ロケール ロケールを区別しない文字列に対して正しい結果を得るには、次のようにします。 toLowerCase(Locale.ENGLISH)を使用してください。

私はこれらのリンクがあなたの問題に対する解決策だと考えています。 を参考にさせていただきました。

**FROM THE LINKS**

toLowerCase() は国際化 (i18n) を尊重します。これは 大文字小文字の変換を行います。を呼び出すと、内部的には を呼び出すと、内部では 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

参照 3



Dotless-iは、ドットのない小文字の'i'です。この文字の大文字は通常の"I"です。もう一つの文字、"I with dot"があります。この文字の小文字は通常の小文字の"i"です。

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

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

私は以前、2 つの深刻な例についてブログに書きました。名前に "i" を含むスクリプト ライブラリでのコンパイル エラーと、名前に "I" を含むデータベース内に XPage がある場合の XSP マネージャーの不具合についてです。

私が言ったように、長い歴史があります。たとえば、いくつかの R7 バージョンでは、受信者の名前が "I" で始まる場合、ルーターは受信者にメッセージを送ることができませんでした。メッセージ報告エージェントは、R8までトルコ語ロケールで動作していませんでした。トルコ語ロケールの人は、Lotus Notes 8.5.1をインストールできませんでした(本当です!)。リストは続きます...

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

Javaチームでさえ、最新のドキュメントに特別な警告を追加しています。

このメソッドはロケールに依存します。 ロケールに依存せず解釈されることを意図している文字列に対して使用された場合、予期しない結果を生む可能性があります。 に依存せず解釈されることを意図している文字列に対して使用すると、予期しない結果をもたらすかもしれません。例としては、プログラミング言語の識別子、プロトコル キー、HTML タグなどです。例えば、トルコ語のロケールでは "TITLE".toLowerCase() は ここで 'ı' は LATIN SMALL LETTER DOTLESS I です。 文字です。ロケールに依存しない文字列に対して正しい結果を得るには、以下のようにします。 toLowerCase(Locale.ENGLISH)を使ってください。