【问题标题】:Python UTF-8 Lowercase Turkish Specific LetterPython UTF-8 小写土耳其语特定字母
【发布时间】:2013-10-02 13:57:23
【问题描述】:

使用 python 2.7:

>myCity = 'Isparta'
>myCity.lower()
>'isparta'
#-should be-
>'ısparta'

尝试了一些解码,(例如,myCity.decode("utf-8").lower()) 但找不到如何做到这一点。

怎样才能降低这种字母? ('I' > 'ı', 'İ' > 'i' 等)

编辑:在土耳其语中,“I”的小写字母是“ı”。 'i'的大写是'İ'

【问题讨论】:

  • 那是 ASCII 大写字母吗?如果它是一些 看起来 像 ASCII 字符的非 ASCII 字符,最好明确地命名它(例如,通过包含代码点)。
  • 是ASCII大写字母I。
  • @KenB:例如土耳其语。这就是为什么这种文化是a common test for i18n-proofing code that compares user input with string literals
  • @Jeff Atwood 曾经写过这篇文章,你最好阅读一下this article 另外,我猜这是关于土耳其语言环境的最佳文章。
  • 那真是太有趣了。我今天学了些新东西。 @FallenAngel,很棒的链接

标签: python unicode encoding utf-8


【解决方案1】:

有些人建议使用tr_TR.utf8 语言环境。至少在 Ubuntu 上,可能与 this bug 有关,设置此语言环境不会产生所需的结果:

import locale
locale.setlocale(locale.LC_ALL, 'tr_TR.utf8')

myCity = u'Isparta İsparta'
print(myCity.lower())
# isparta isparta

因此,如果此错误影响到您,作为一种解决方法,您可以自己执行此翻译:

lower_map = {
    ord(u'I'): u'ı',
    ord(u'İ'): u'i',
    }

myCity = u'Isparta İsparta'
lowerCity = myCity.translate(lower_map)
print(lowerCity)
# ısparta isparta

打印

ısparta isparta

【讨论】:

  • 其实有一个。
  • 显然这是一个迟到的评论,但至少对于 python 3.7,没有区域设置敏感的大小写比较。请参阅语言环境页面上的here
【解决方案2】:

您应该使用来自 emre's solution 的 unicode 的新派生类

class unicode_tr(unicode):
    CHARMAP = {
        "to_upper": {
            u"ı": u"I",
            u"i": u"İ",
        },
        "to_lower": {
            u"I": u"ı",
            u"İ": u"i",
        }
    }

    def lower(self):
        for key, value in self.CHARMAP.get("to_lower").items():
            self = self.replace(key, value)
        return self.lower()

    def upper(self):
        for key, value in self.CHARMAP.get("to_upper").items():
            self = self.replace(key, value)
        return self.upper()

if __name__ == '__main__':
    print unicode_tr("kitap").upper()
    print unicode_tr("KİTAP").lower()

给予

KİTAP
kitap

这一定能解决你的问题。

【讨论】:

  • 请注意,link-only answers are discouraged,SO 答案应该是搜索解决方案的终点(相对于另一个参考中途停留,随着时间的推移往往会变得陈旧)。请考虑在此处添加独立的概要,并保留链接作为参考。
【解决方案3】:

我通过猴子补丁方法对内置的 unicode 模块进行了分叉和重新设计了 Emre 的解决方案。这种新方法的优点是不需要使用 unicode 的子类和 通过my_unicode_string = unicode_tr(u'bla bla bla')重新定义unicode字符串 只需导入此模块,即可与内置的原生 unicode 字符串无缝集成

https://github.com/technic-programming/unicode_tr

# -*- coding: utf8 -*-
# Redesigned by @guneysus

import __builtin__
from forbiddenfruit import curse

lcase_table = tuple(u'abcçdefgğhıijklmnoöprsştuüvyz')
ucase_table = tuple(u'ABCÇDEFGĞHIİJKLMNOÖPRSŞTUÜVYZ')

def upper(data):
    data = data.replace('i',u'İ')
    data = data.replace(u'ı',u'I')
    result = ''
    for char in data:
        try:
            char_index = lcase_table.index(char)
            ucase_char = ucase_table[char_index]
        except:
            ucase_char = char
        result += ucase_char
    return result

def lower(data):
    data = data.replace(u'İ',u'i')
    data = data.replace(u'I',u'ı')
    result = ''
    for char in data:
        try:
            char_index = ucase_table.index(char)
            lcase_char = lcase_table[char_index]
        except:
            lcase_char = char
        result += lcase_char
    return result

def capitalize(data):
    return data[0].upper() + data[1:].lower()

def title(data):
    return " ".join(map(lambda x: x.capitalize(), data.split()))

curse(__builtin__.unicode, 'upper', upper)
curse(__builtin__.unicode, 'lower', lower)
curse(__builtin__.unicode, 'capitalize', capitalize)
curse(__builtin__.unicode, 'title', title)

if __name__ == '__main__':
    print u'istanbul'.upper()
    print u'İSTANBUL'.lower()

【讨论】:

    【解决方案4】:

    您可以在更改为上/下之前使用 .replace() 函数。在你的情况下:

        myCity.replace('I', 'ı').lower()
    

    【讨论】:

      【解决方案5】:

      您需要使用locale.setLocale() 设置正确的语言环境(我猜是tr-TR)。否则将使用默认的上下映射,如果该默认值为 en-US,则I 的小写版本为i

      【讨论】:

      • 我否决了这个答案,因为将语言环境设置为 tr_TR 不会改变 str.upper/str.lower 在字母 i/I 上的行为。
      猜你喜欢
      • 1970-01-01
      • 2014-05-04
      • 1970-01-01
      • 2013-08-22
      • 2014-04-16
      • 1970-01-01
      • 2014-07-25
      • 2014-02-09
      • 2010-12-23
      相关资源
      最近更新 更多