python - 正确处理土耳其语大写和小写,需要修改/覆盖内置函数?
问题描述
我正在处理多语言文本数据,其中包括使用西里尔字母和土耳其语的俄语。我基本上必须比较两个文件中my_file
的check_file
单词,如果my_file
可以在 中找到单词,check_file
则将它们写入输出文件,保留两个输入文件中关于这些单词的元信息。
有些单词是小写的,而其他单词是大写的,所以我必须将所有单词都小写来比较它们。由于我使用 Python 3.6.5 而 Python 3 默认使用 unicode,因此它会处理小写字母,然后再将西里尔字母的单词正确大写。然而,对于土耳其语,有些字母处理不正确。大写'İ'
应该对应小写'i'
,大写'I'
应该对应小写'ı'
,小写'i'
应该对应大写'İ'
,如果我在控制台中键入以下内容,情况并非如此:
>>> print('İ'.lower())
i̇ # somewhat not rendered correctly, corresponds to unicode 'i\u0307'
>>> print('I'.lower())
i
>>> print('i'.upper())
I
我正在执行以下操作(简化示例代码):
# python my_file check_file language
import sys
language = sys.argv[3]
# code to get the files as lists
my_file_list = [['ıspanak', 'N'], ['ısır', 'N'], ['acık', 'V']]
check_file_list = [['109', 'Ispanak', 'food_drink'], ['470', 'Isır', 'action_words'], [409, 'Acık', 'action_words']]
# get the lists as dict
my_dict = {}
check_dict = {}
for l in my_file_list:
word = l[0].lower()
pos = l[1]
my_dict[word] = pos
for l in check_file_list:
word_id = l[0]
word = l[1].lower()
word_cat = l[2]
check_dict[word] = [word_id, word_cat]
# compare the two dicts
for word, pos in my_dict.items():
if word in check_dict:
word_id = check_dict[word][0]
word_cat = check_dict[word][1]
print(word, pos, word_id, word_cat)
这只给了我一个结果,但它应该给我三个词作为结果:
acık V 409 action_words
到目前为止,我根据这个问题做了什么:
- 阅读建议使用PyICU的已接受答案,但我希望我的代码无需安装即可使用,所以我没有实现它。
- 尝试
import locale
并locale.setlocale(locale.LC_ALL, 'tr_TR.UTF-8')
如问题中提到的那样,但它没有改变任何东西。 如第二个答案中所述,实现两个功能
turkish_lower(self)
和turkish_upper(self)
三个有问题的字母,这似乎是唯一的解决方案:def turkish_lower(self): self = re.sub(r'İ', 'i', self) self = re.sub(r'I', 'ı', self) self = self.lower() return self def turkish_upper(self): self = re.sub(r'i', 'İ', self) self = self.upper() return self
但是我怎样才能使用这两个功能而不必if language == 'Turkish'
每次都检查呢?lower()
我应该覆盖内置函数upper()
吗?如果是,那么pythonic的做法是什么?我应该为我正在使用的各种语言实现类并覆盖土耳其语类中的内置函数吗?
解决方案
您可以创建一个简单的“语言感知”字符串,将其子类str
化并进行正确的大写和小写,例如:
class LanguageAwareStr(str):
lang = None
class RussianStr(LanguageAwareStr):
lang = 'ru'
class TurkishStr(LanguageAwareStr):
lang = 'tr'
_case_lookup_upper = {'İ': 'i', 'I': 'ı'} # lookup uppercase letters
_case_lookup_lower = {v: k for (k, v) in _case_lookup_upper.items()}
# here we override the lower() and upper() methods
def lower(self):
chars = [self._case_lookup_upper.get(c, c) for c in self]
result = ''.join(chars).lower()
cls = type(self) # so we return a TurkishStr result
return cls(result)
def upper(self):
chars = [self._case_lookup_lower.get(c, c) for c in self]
result = ''.join(chars).upper()
cls = type(self) # so we return a TurkishStr result
return cls(result)
然后当你读取一个字符串,知道它是什么语言时,你将它包装在适当的 LanguageAwareStr 子类中,然后定期使用它:
from langaware import RussianStr, TurkishStr
if language == 'turkish':
LangStr = TurkishStr # can also create a dict to lookup the correct class
然后,当您阅读语言字符串时,您只需将它们包装在对以下的调用中LangStr()
:
for l in my_file_list:
word = LangStr(l[0]).lower()
pos = l[1]
my_dict[word] = pos
for l in check_file_list:
word_id = l[0]
word = LangStr(l[1]).lower()
word_cat = l[2]
check_dict[word] = [word_id, word_cat]
推荐阅读
- c++ - 如何删除所有子路径?
- python - Pandas,groupby 操作列
- javascript - 通过正则表达式解析url结构
- google-cloud-platform - 谷歌云平台:使用gpu监控时权限被拒绝
- javascript - HttpPost 控制器参数 null ASP.NET CORE MVC
- python - 是否可以获得对用于创建字典对象的 TypedDict 类的引用?
- oracle - Oracle 的 cx_oracle 和 Instantclient 软件包在 anaconda/win-64 上不可用
- angular - 停止应用程序的初始化,直到调用 ngrx 的操作
- mongodb - MongoDB:副本集和循环查询分布?
- sql - 使用 PostgreSQL \COPY