String.maketrans用于英语和波斯语数字

Sha*_*ism 6 python python-2.7 python-unicode

我有这样的功能:

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)
Run Code Online (Sandbox Code Playgroud)

我希望它将所有阿拉伯语和英语数字翻译成波斯语.但Python说:

english_translate = string.maketrans(english_numbers, persian_numbers)
ValueError: maketrans arguments must have same length
Run Code Online (Sandbox Code Playgroud)

我试图用Unicode编码字符串,utf-8但我总是遇到一些错误!有时问题是阿拉伯字符串而不是!你知道更好的解决方案吗?

编辑:

似乎问题是ASCII中的Unicode字符长度.像'?'这样的阿拉伯数字 是两个角色 - 我发现了ord().长度问题从这里开始:-(

jsb*_*eno 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)
Run Code Online (Sandbox Code Playgroud)

尝试"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
>>> 
Run Code Online (Sandbox Code Playgroud)

顺便说一句,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'
Run Code Online (Sandbox Code Playgroud)

因此,字符在"单个实体"和编码时作为数字失去意义 - 编码对象(Python 2.x中的str类型)只是字节的大小 - 当将这些字符发送到程序的任何输出时仍然需要它们 - 无论是控制台,GUI窗口,数据库,HTML代码等...


F.T*_*amy 10

请参阅unidecode库,它将所有字符串转换为UTF8.在使用不同语言输入数字时非常有用.

在Python 2中:

>>> from unidecode import unidecode
>>> a = unidecode(u"??????????")
>>> a
'0123456789'
>>> unidecode(a)
'0123456789'
Run Code Online (Sandbox Code Playgroud)

在Python 3中:

>>> from unidecode import unidecode
>>> a = unidecode("??????????")
>>> a
'0123456789'
>>> unidecode(a)
'0123456789'
Run Code Online (Sandbox Code Playgroud)


小智 6

unidecode 将所有字符从波斯语转换为英语,如果您只想更改数字,请执行以下操作:

在python3中,您可以使用此代码将任何波斯|阿拉伯数字转换为英文数字,​​同时保持其他字符不变:

intab='????????????????????'
outtab='12345678901234567890'
translation_table = str.maketrans(intab, outtab)
output_text = input_text.translate(translation_table)
Run Code Online (Sandbox Code Playgroud)


Maj*_*jid 5

您可以使用persiantools包:

例子:

>>> from persiantools import digits

>>> digits.en_to_fa("0987654321")
'??????????'

>>> digits.ar_to_fa("??????????")   # or digits.ar_to_fa(u"??????????")
'??????????'
Run Code Online (Sandbox Code Playgroud)