Регулярное выражение, которое находит и заменяет не-ascii символы на Python - PullRequest
3 голосов
/ 03 мая 2010

Мне нужно изменить некоторые символы, которые не являются ASCII, на '_'. Например,

Tannh‰user -> Tannh_user
  • Если я использую регулярное выражение с Python, как я могу это сделать?
  • Есть ли лучший способ сделать это, не используя RE?

Ответы [ 6 ]

9 голосов
/ 03 мая 2010
re.sub(r'[^\x00-\x7F]', '_', theString)

Это будет работать, если строка является Unicode, или строка в кодировке, где ASCII занимает значения от 0 до 0x7F (латинский-1, UTF-8 и т.

5 голосов
/ 03 мая 2010

Использование поддержки Python для кодировки символов:

# coding: utf8
import codecs

def underscorereplace_errors(exc):
  return (u'_', exc.end)

codecs.register_error('underscorereplace', underscorereplace_errors)

print u'Tannh‰user'.encode('ascii', 'underscorereplace')
4 голосов
/ 03 мая 2010

Обновлено для Python 3:

>>> 'Tannh‰user'.encode().decode('ascii', 'replace').replace(u'\ufffd', '_')
'Tannh___user'

Сначала мы создаем строку байтов, используя encode() - по умолчанию используется кодек UTF-8. Если у вас есть строка байтов, то, конечно, пропустите этот шаг кодирования. Затем мы конвертируем ее в «обычную» строку, используя кодек ascii.

При этом используется свойство UTF-8, согласно которому все не-ascii символы кодируются как последовательность байтов со значением> = 0x80.


Оригинальный ответ - для Python 2:

Как это сделать, используя встроенный str.decode метод:

>>> 'Tannh‰user'.decode('ascii', 'replace').replace(u'\ufffd', '_')
u'Tannh___user'

(Вы получаете unicode строку, поэтому конвертируйте ее в str, если вам нужно.)

Вы также можете конвертировать unicode в str, поэтому один не-ASCII символ заменяется на ASCII. Но проблема в том, что unicode.encode с replace переводит не-ASCII символы в '?', поэтому вы не знаете, был ли знак вопроса там уже раньше; см. решение от Игнасио Васкеса-Абрамса.


Другой способ, используя ord() и сравнивая значение каждого символа, если он вписывается в диапазон ASCII (0-127) - это работает для unicode строк и для str в utf-8, латинской и некоторых других кодировках :

>>> s = 'Tannh‰user' # or u'Tannh‰user' in Python 2
>>> 
>>> ''.join(c if ord(c) < 128 else '_' for c in s)
'Tannh_user'
2 голосов
/ 03 мая 2010

Я бы предпочел просто вызвать ord для каждого символа в строке, 1 на 1. Если ord([char]) >= 128, то этот символ не является символом ascii и должен быть заменен.

1 голос
/ 24 июля 2018

Чтобы ответить на вопрос

'[\u0080-\uFFFF]'

будет соответствовать любому символу UTF-8, не входящему в диапазон первых 128 символов

re.sub('[\u0080-\uFFFF]+', '_', x)

заменит любую последовательность последовательных символов nonascii на подчеркивание

1 голос
/ 03 мая 2010

если вы знаете, какие символы вы хотите заменить, вы можете применить строковые методы

mystring.replace('oldchar', 'newchar')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...