11

キャラクターを大文字にするのは複雑な仕事であることがわかりました。基本的なASCII文字セットから抜け出す場合、文字の大文字と小文字の規則は、実際にはアプリケーションが実行されているロケールに依存します。

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

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

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

今、私はこれをCで完璧に行うことができます。Haskellでこれを行うにはどうすればよいですか?私が行うすべての検索は、ロケールを認識しないData.Char.toUpperを直接指し示します。ロケールを認識する関数は見つかりませんでした。


これがCのコードサンプルです。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
4

1 に答える 1

13

パッケージのData.Text.ICU.toUpper関数を使用します。text-icu

toUpper :: LocaleName -> Text -> Text

文字列内の文字を大文字にします。

ケーシングはロケールに依存し、コンテキストに依存します。結果は、元の結果よりも長くなったり短くなったりする場合があります。

于 2012-09-21T20:44:44.900 に答える