我正在使用多语言文本数据,其中包括使用西里尔字母和土耳其语的俄语。我基本上必须比较两个文件my_file
和check_file
中的单词,如果可以在my_file
中找到check_file
中的单词,请将它们写入保存元文件的输出文件中 - 从两个输入文件中获取有关这些单词的信息。
有些单词是小写的,而其他单词是大写的,所以我必须小写所有单词来比较它们。当我使用Python 3.6.5并且Python 3使用unicode作为默认值时,它会处理小写,然后为Cyrillic正确地大写单词。但是对于土耳其语,有些字母处理不正确。大写'İ'
应对应小写'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
到目前为止我基于this question做了什么:
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的做法是什么?我应该为我正在使用的各种语言实现类,并覆盖土耳其语类中的内置函数吗?
答案 0 :(得分:0)
我建议尝试为区域设置安装土耳其语语言包:
sudo apt-get install language-pack-tr
sudo dpkg-reconfigure locales # *
您还可以使用终端命令$ locale -a
答案 1 :(得分:0)
您可以创建一个简单的“语言识别”字符串,该字符串将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]