我们的一些客户提交时间戳,如٢٠١٥-١٠-٠٣١٩:٠١:٤٣谷歌翻译为"03/10/2015 19:01:43"。链接在这里。
如何在 Python 中实现相同的目标?
还有来自 https://pypi.python.org/pypi/Unidecode 的unidecode
库。
在 Python 2 中:
>>> from unidecode import unidecode
>>> unidecode(u"۰۱۲۳۴۵۶۷۸۹")
'0123456789'
在 Python 3 中:
>>> from unidecode import unidecode
>>> unidecode("۰۱۲۳۴۵۶۷۸۹")
'0123456789'
要将时间字符串转换为日期时间对象(Python 3(:
>>> import re
>>> from datetime import datetime
>>> datetime(*map(int, re.findall(r'd+', ' ٢٠١٥-١٠-٠٣ ١٩:٠١:٤٣')))
datetime.datetime(2015, 10, 3, 19, 1, 43)
>>> str(_)
'2015-10-03 19:01:43'
如果您只需要数字:
>>> list(map(int, re.findall(r'd+', ' ٢٠١٥-١٠-٠٣ ١٩:٠١:٤٣')))
[2015, 10, 3, 19, 1, 43]
我的解决方案在不同的时间戳下失败:u'۲۰۱۵-۱۰-۱۸ ۰۸:۲۲:۱۱'。选择J.F. Sebastian或jimhark的解决方案。
使用ord
获取 unicode 代码点。数字从 1632 (0( 开始。
d = u'٢٠١٥-١٠-٠٣ ١٩:٠١:٤٣'
s = []
for c in d:
o = ord(c)
print '%s -> %s, %s - 1632 = %s' %(c, o, o, o - 1632)
if 1631 < o < 1642:
s.append(str(o - 1632))
continue
s.append(c)
print ''.join(s)
#or as a one liner:
print ''.join([str(ord(c)-1632) if 1631 < ord(c) < 1642 else c for c in d])
下面是 for 循环的输出:
٢ -> 1634, 1634 - 1632 = 2
٠ -> 1632, 1632 - 1632 = 0
١ -> 1633, 1633 - 1632 = 1
٥ -> 1637, 1637 - 1632 = 5
- -> 45, 45 - 1632 = -1587
١ -> 1633, 1633 - 1632 = 1
٠ -> 1632, 1632 - 1632 = 0
- -> 45, 45 - 1632 = -1587
٠ -> 1632, 1632 - 1632 = 0
٣ -> 1635, 1635 - 1632 = 3
-> 32, 32 - 1632 = -1600
١ -> 1633, 1633 - 1632 = 1
٩ -> 1641, 1641 - 1632 = 9
: -> 58, 58 - 1632 = -1574
٠ -> 1632, 1632 - 1632 = 0
١ -> 1633, 1633 - 1632 = 1
: -> 58, 58 - 1632 = -1574
٤ -> 1636, 1636 - 1632 = 4
٣ -> 1635, 1635 - 1632 = 3
2015-10-03 19:01:43
虽然受到其他一些答案的启发(谢谢@kev(,但我采取了不同的方法。
(嘟!我刚刚注意到@kev也问了这个问题。
您专门询问了阿拉伯字符,但它简化了处理所有 Unicode 数字的过程。
注意:我处理相同的日期字符串,但使用 Unicode 转义序列指定 Unicode 字符,因为这在我的系统上更容易。
import unicodedata
unicodeDate = u'u0662u0660u0661u0665-u0661u0660-u0660u0663 u0661u0669:u0660u0661:u0664u0663'
converted = u''.join([unicode(unicodedata.decimal(c, c)) for c in unicodeDate])
print converted
unicodedata.decimal 的第二个参数是第一个参数未映射到 Unicode 十进制时返回的默认值。为两个参数传递相同字符的效果是,任何 Unicode 十进制都转换为等效的 ASCII 十进制,所有其他字符传递不变。
我的原始答案
converted = ''.join([str(unicodedata.digit(c, c)) for c in unicodeDate])
@J.F. Sebastian,提供了一个有用的注释,指出上面的代码不能正确处理超级脚本,例如u'\u00b2'。同一组中还有上标:"\u00b3",u'\u00b9"。我发现这也会影响以下一些代码点:
- 上标和下标 (2070–209F(
- 封闭式字母数字 (2460–24FF(
- 丁蝙蝠 (2700–27BF(
显然,unicodedata.digit()
试图从装饰的数字中提取一个数字,这在这里可能不可取。但unicodedata.decimal
似乎它完全符合要求(假设您不想转换装饰数字(。