Python: Как я могу заменить полноширинные символы полуширинными символами?

Если бы это было PHP, то я, вероятно, сделал бы что-то вроде этого:

function no_more_half_widths($string){
  $foo = array('1','2','3','4','5','6','7','8','9','10')
  $bar = array('1','2','3','4','5','6','7','8','9','10')
  return str_replace($foo, $bar, $string)
}

Я попробовал функцию .translate в Python, и это указывает, что массивы не имеют того же размера. Я предполагаю, что это - то, вследствие того, что отдельные символы кодируются в utf-8. Какие-либо предложения?

10
задан ghostdog74 11 March 2010 в 02:43
поделиться

4 ответа

Это может сделать встроенный модуль unicodedata:

>>> import unicodedata
>>> foo = u'1234567890'
>>> unicodedata.normalize('NFKC', foo)
u'1234567890'

"NFKC" означает "Normalization Form KC [Compatibility Decomposition, followed by Canonical Composition]", и заменяет полноширокие символы на полуширокие, которые эквивалентны Unicode.

Обратите внимание, что одновременно с этим нормализуется и множество других вещей, например, отдельные знаки ударения и символы римских цифр.

22
ответ дан 3 December 2019 в 14:06
поделиться

Я не думаю, что есть встроенная функция для выполнения нескольких замен за один проход, поэтому вам придется делать это самостоятельно.

Один из способов сделать это:

>>> src = (u'1',u'2',u'3',u'4',u'5',u'6',u'7',u'8',u'9',u'10')
>>> dst = ('1','2','3','4','5','6','7','8','9','0')
>>> string = u'a123'
>>> for i, j in zip(src, dst):
...     string = string.replace(i, j)
... 
>>> string
u'a123'

Или использовать словарь:

>>> trans = {u'1': '1', u'2': '2', u'3': '3', u'4': '4', u'5': '5', u'6': '6', u'7': '7', u'8': '8', u'9': '9', u'0': '0'}
>>> string = u'a123'
>>> for i, j in trans.iteritems():
...     string = string.replace(i, j)
...     
>>> string
u'a123'

Или, наконец, использовать регулярное выражение (и это может быть самым быстрым):

>>> import re
>>> trans = {u'1': '1', u'2': '2', u'3': '3', u'4': '4', u'5': '5', u'6': '6', u'7': '7', u'8': '8', u'9': '9', u'0': '0'}
>>> lookup = re.compile(u'|'.join(trans.keys()), re.UNICODE)
>>> string = u'a123'
>>> lookup.sub(lambda x: trans[x.group()], string)
u'a123'
3
ответ дан 3 December 2019 в 14:06
поделиться

Использование метода unicode.translate :

>>> table = dict(zip(map(ord,u'0123456789'),map(ord,u'0123456789')))
>>> print u'123'.translate(table)
123

Требуется отображение кодовых точек как чисел , а не символов. Кроме того, использование u'unicode literals ' оставляет значения незакодированными.

3
ответ дан 3 December 2019 в 14:06
поделиться

Подход с использованием регулярных выражений

>>> import re
>>> re.sub(u"[\uff10-\uff19]",lambda x:chr(ord(x.group(0))-0xfee0),u"456")
u'456'
3
ответ дан 3 December 2019 в 14:06
поделиться
Другие вопросы по тегам:

Похожие вопросы: