2012-09-21 12 views
10

के संबंध में एक यूनिकोड चरित्र को अपरकेस कैसे कर सकता हूं यह पता चला है कि एक चरित्र को अपरकेसिंग करना एक जटिल व्यवसाय है। यदि आप मूल ASCII चरित्र सेट से बाहर निकलते हैं, तो चरित्र को अपरकेसिंग करने और किसी चरित्र को कम करने के नियम वास्तव में उस लोकेल पर निर्भर होते हैं जिसमें एप्लिकेशन चल रहा है।हैकेल में मैं वर्तमान लोकेल

डेमो एप्लिकेशन के रूप में, मैं '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) 

अब, मैं इसे पूरी तरह से कर सकता हूं सी। मैं इसे हास्केल में कैसे कर सकता हूं? मैं जो खोज करता हूं वह मुझे सीधे डेटा पर इंगित करता है। Char.toUpper, जो लोकेल-जागरूक नहीं है। मुझे कोई भी कार्य नहीं मिला है जो किसी भी तरह से लोक-जागरूक हैं।


यहां से सी कोड नमूना है। मैं इसे अपने लिनक्स मशीन पर चलाता हूं।

#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

उदाहरण। मैं सॉफ़्टवेयर पर काम कर रहा हूं कि जब मैं इसमें दौड़ना शुरू करता हूं, तो हम बहुराष्ट्रीय रूप से रिलीज करने जा रहे हैं, और उसके बाद जी + पर इसके बारे में बात करने में मुझे बहुत सारे दोस्त मिल गए, जिनमें तकनीकी नहीं हैं, समस्या में रूचि रखते हैं। मैंने सोचा था कि सप्ताहांत में मैं सॉफ्टवेयर का एक टुकड़ा विकसित करूंगा जिसने बहुत कुछ प्रदर्शित किया, लेकिन कभी मौका नहीं मिला। –

उत्तर

13

उपयोग text-icu पैकेज से Data.Text.ICU.toUpper समारोह है।

toUpper :: LocaleName -> Text -> Text

अपरकेस एक स्ट्रिंग में वर्णों।

आवरण लोकेल निर्भर और संदर्भ संवेदनशील है। नतीजा मूल से लंबा या छोटा हो सकता है।

+0

वह बिल्कुल था! यह अधिकांश यूनिकोड समर्थन की तरह दिखता है, मुझे प्रीलूड PutStrLn, Data.Text.ICU (लोकेल-निर्भर ऊपरी और लोअरकेस के लिए), और डेटा.Text (यूनिकोड तारों के निर्माण के लिए) से परे कुछ भी नहीं चाहिए। शायद यूटीएफ -8 और आंतरिक प्रतिनिधित्व के बीच स्विच करने के लिए यूनिकोड कोडेक फ़ंक्शन भी। –