2012-09-21 4 views
10

文字を大文字にすることは複雑なビジネスです。基本的なASCII文字セットから抜け出すと、文字の大文字化と文字の小文字化のルールは、実際にはアプリケーションが動作しているロケールに依存します。haskellで現在のロケールに対してUnicode文字を大文字にする方法

デモアプリケーションとして、文字「i」(ドット付き)と文字「i」(ドットなし)を大文字で入力しようとしています。今、en_USでは、 'i'(ドット付き)は 'I'に、 'i'(ドットなし)は存在しません(しかし、 'I'にはまだ大文字です)。

しかし、トルコ語(tr_TR.UTF-8)に切り替えると 'i'(ドット付き)は 'İ'(ドットも含む)と 'ı'(ドットなし)を大文字にする必要があります「私」にも(ドットなしで)。小文字はこれらの操作を逆にする必要があります。

iİıI --> İİII (tr_TR.UTF-8) 
iİıI --> IİII (en_US.UTF-8) 

ここで、私はCでこれを完全に行うことができます。どのようにしてHaskellで行うことができますか?私が検索したすべての検索では、Data.Char.toUpperが直接ロケール対応ではありません。私は、ロケールを意識した関数を見つけられませんでした。


私のLinuxマシンで実行したコードサンプルです。

#include <stdio.h> 
#include <stdlib.h> 
#include <locale.h> 
#include <wctype.h> 
#include <string.h> 
#include <errno.h> 

wchar_t latin_small_sharp_s[5] = {0x00df, 0x00df, 0x0053, 0x0053, 0}; 
wchar_t turkish_is[5] = {0x0069, 0x0130, 0x0131, 0x0049, 0}; 

char multibyte_turkish_is[7] = {0x69, 0x01, 0x30, 0x01, 0x31, 0x49, 0}; 

void print_in_locale (const char *locale, const wchar_t *str, const size_t len) { 
    wchar_t *dest = calloc(len * 2, sizeof(wchar_t)); 
    int i; 

    if (!setlocale(LC_CTYPE, locale)) { 
    fprintf(stderr, "Locale %s failed with error: %s", locale, strerror(errno)); 
    exit(1); 
    } 

    for (i = 0; i < len; i++) { 
    dest[i] = towupper(str[i]); 
    } 
    printf("%ls, %ls\n", str, dest); 
    free(dest); 
} 

int main() { 
    print_in_locale("de_DE.utf8", latin_small_sharp_s, 5); 
    print_in_locale("tr_TR.utf8", turkish_is, 5); 
    print_in_locale("de_DE.utf8", turkish_is, 5); 
} 

あなたが「locale_test.c」にそれを保存した場合、あなたはコマンドラインで実行することができますが...

gcc -o locale_test locale_test.c && ./locale_test 
+0

トルコ語のみを例として使用しましたか、トルコを対象としたソフトウェアを開発しましたか? –

+1

例。私はソフトウェアに取り組んでいます。私がこれに就き始めたときに多国語でリリースするつもりです。それから、G +で話をすると、技術者ではなく問題に興味のある人を含めて多くの友人がいます。私は週末にこれを多く実証したが、決してチャンスがないソフトウェアを開発すると思っていた。 –

答えて

13

text-icuパッケージからData.Text.ICU.toUpper機能を使用してください。文字列内の文字大文字

toUpper :: LocaleName -> Text -> Text

ケーシングはロケールに依存し、コンテキストに依存します。結果は、元よりも長くても短くても、 になる可能性があります。

+0

それはまさにそれでした!私はPrelude putStrLn、Data.Text.ICU(ロケールに依存する大文字と小文字)、Data.Text(ユニコード文字列を作成する)以外のものは必要ありません。おそらくUTF-8と内部表現を切り替えるユニコードコーデック機能もあります。 –

関連する問題