我有这样的功能:
persian_numbers = '۱۲۳۴۵۶۷۸۹۰'
english_numbers = '1234567890'
arabic_numbers = '١٢٣٤٥٦٧٨٩٠'
english_trans = string.maketrans(english_numbers, persian_numbers)
arabic_trans = string.maketrans(arabic_numbers, persian_numbers)
text.translate(english_trans)
text.translate(arabic_trans)
我希望它将所有阿拉伯语和英语数字翻译成波斯语。但Python说:
english_translate = string.maketrans(english_numbers, persian_numbers)
ValueError: maketrans arguments must have same length
我尝试使用Unicode utf-8
对字符串进行编码,但我总是遇到一些错误!有时问题是阿拉伯字符串而不是!你知道更好的解决方案吗?
似乎问题是ASCII中的Unicode字符长度。像'1'这样的阿拉伯数字是两个字符 - 我发现ord()
。长度问题从这里开始: - (
答案 0 :(得分:11)
Unicode对象可以将这些数字(阿拉伯语和波斯语)解释为实际数字 - 无需使用字符替换来翻译它们。
编辑 - 我想出了一种使用Python2正则表达式进行替换的方法:
# coding: utf-8
import re
# Attention: while the characters for the strings bellow are
# dislplayed indentically, inside they are represented
# by distinct unicode codepoints
persian_numbers = u'۱۲۳۴۵۶۷۸۹۰'
arabic_numbers = u'١٢٣٤٥٦٧٨٩٠'
english_numbers = u'1234567890'
persian_regexp = u"(%s)" % u"|".join(persian_numbers)
arabic_regexp = u"(%s)" % u"|".join(arabic_numbers)
def _sub(match_object, digits):
return english_numbers[digits.find(match_object.group(0))]
def _sub_arabic(match_object):
return _sub(match_object, arabic_numbers)
def _sub_persian(match_object):
return _sub(match_object, persian_numbers)
def replace_arabic(text):
return re.sub(arabic_regexp, _sub_arabic, text)
def replace_persian(text):
return re.sub(arabic_regexp, _sub_persian, text)
尝试“text”参数必须是unicode本身。
(也可以缩短此代码 通过使用lambdas并在一行中组合一些表达式,但没有必要这样做,但是为了失去可读性)
它应该对你有用,但请阅读我发布的原始答案
- 原始回答
因此,如果将变量实例化为unicode(将u添加到引号char),则可以在Python中正确理解它们:
>>> persian_numbers = u'۱۲۳۴۵۶۷۸۹۰'
>>> english_numbers = u'1234567890'
>>> arabic_numbers = u'١٢٣٤٥٦٧٨٩٠'
>>>
>>> print int(persian_numbers)
1234567890
>>> print int(english_numbers)
1234567890
>>> print int(arabic_numbers)
1234567890
>>> persian_numbers.isdigit()
True
>>>
顺便说一句,unicode对象不存在“maketrans”方法(在Python2中 - 参见注释)。
了解unicode的基本知识非常重要 - 对于每个人来说,即使是只写英语的人也认为他们永远不会处理26封拉丁字母中的任何字符。在编写处理不同字符的代码时,这是至关重要的 - 如果不知道你在做什么,程序就不可能工作,除非偶然。
一篇非常好的文章是http://www.joelonsoftware.com/articles/Unicode.html - 请现在阅读。 您可以记住,在阅读它时,Python允许通过使用unicode对象的“encode”方法将unicode字符转换为任何“物理”编码的字符串。
>>> arabic_numbers = u'١٢٣٤٥٦٧٨٩٠'
>>> len(arabic_numbers)
10
>>> enc_arabic = arabic_numbers.encode("utf-8")
>>> print enc_arabic
١٢٣٤٥٦٧٨٩٠
>>> len(enc_arabic)
20
>>> int(enc_arabic)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 10: '\xd9\xa1\xd9\xa2\xd9\xa3\xd9\xa4\xd9\xa5\xd9\xa6\xd9\xa7\xd9\xa8\xd9\xa9\xd9\xa0'
因此,字符在“单个实体”和作为编码时的数字时都会失去意义 - 编码对象(Python 2.x中的str类型)只是字节的大小 - 在将这些字符发送到任何输出时仍然需要从程序 - 无论是控制台,GUI窗口,数据库,HTML代码等...
答案 1 :(得分:10)
请参阅unidecode库,将所有字符串转换为UTF8。在输入不同语言的数字时非常有用。
在Python 2中:
>>> from unidecode import unidecode
>>> a = unidecode(u"۰۱۲۳۴۵۶۷۸۹")
>>> a
'0123456789'
>>> unidecode(a)
'0123456789'
在Python 3中:
>>> from unidecode import unidecode
>>> a = unidecode("۰۱۲۳۴۵۶۷۸۹")
>>> a
'0123456789'
>>> unidecode(a)
'0123456789'
答案 2 :(得分:3)
unidecode
将所有字符从波斯语转换为英语,如果只想更改数字,请遵循以下提示:
在python3中,您可以使用此代码将任何波斯语|阿拉伯数字转换为英文数字,同时保持其他字符不变:
intab='۱۲۳۴۵۶۷۸۹۰١٢٣٤٥٦٧٨٩٠'
outtab='12345678901234567890'
translation_table = str.maketrans(intab, outtab)
output_text = input_text.translate(translation_table)
答案 3 :(得分:1)
使用Unicode字符串:
persian_numbers = u'۱۲۳۴۵۶۷۸۹۰'
english_numbers = u'1234567890'
arabic_numbers = u'١٢٣٤٥٦٧٨٩٠'
确保Python文件的编码正确无误。
答案 4 :(得分:0)
您可以使用persiantools软件包:
示例:
>>> from persiantools import digits
>>> digits.en_to_fa("0987654321")
'۰۹۸۷۶۵۴۳۲۱'
>>> digits.ar_to_fa("٠٩٨٧٦٥٤٣٢١") # or digits.ar_to_fa(u"٠٩٨٧٦٥٤٣٢١")
'۰۹۸۷۶۵۴۳۲۱'