Удалить не буквенно-цифровые символы из строки, но сохранить закодированные символы, отличные от ASCII åäö

Как я могу сохранить åäö, но удалить из строки все остальные небуквенно-цифровые символы? (Я нашел похожие вопросы, но ни один из них, похоже, не имеет правильного ответа.)

Я пробовал такие вещи, как расширение регулярного выражения, чтобы попытаться пропустить åäö в подпрограмме, но, похоже, это просто заставляет регулярное выражение перестать работать вместе, оставляя пробелы и тому подобное. Обычно я не программирую на python, просто пытаюсь помочь другу, поэтому может быть какой-то лучший способ очистить строку, чем использовать re.

Из поиска в Google я думаю, что это связано с Unicode, но нет хороших решений.

def ordnaText(text): 
    text = text.lower()
    text = re.sub('\W', '', text)
    if text.isalnum() == True:
        return text

person A.collin    schedule 19.12.2013    source источник
comment
Это питон 2 или 3?   -  person Martijn Pieters    schedule 19.12.2013
comment
Что такое type(text)?   -  person Eric    schedule 19.12.2013
comment
Я не на 100% уверен, что ты имеешь в виду, Эрик, но это строка? из raw_input   -  person A.collin    schedule 19.12.2013
comment
@A.collin: Это важная информация.   -  person Martijn Pieters    schedule 19.12.2013
comment
@A.collin: Когда вы добавляете строку print type(text) в код, что получается на выходе?   -  person Eric    schedule 19.12.2013


Ответы (3)


Вы пытаетесь сопоставить закодированный ввод; raw_input() в Python 2 всегда возвращает строку байтов. Это означает, что терминал, консоль или IDE, которые вы используете, определяют, какая кодировка используется для ввода.

Попытка сопоставить не-ASCII-символы с регулярным выражением, используя строки байтов, требует, чтобы вы точно сопоставили закодированные байты, что обычно означает, что любое изменение в терминальной среде или настройках вашего редактора исходного кода приведет к матч провален.

Вы хотите явно декодировать raw_input() здесь и использовать сопоставление Unicode:

import sys
import re

def ordnaText(text): 
    text = text.lower()
    text = re.sub(u'\W', '', text, flags=re.UNICODE)
    if text.isalnum() == True:
        return text

userinput = raw_input('....')
userinput = userinput.decode(sys.stdin.encoding)
something = ordnaText(userinput)

sys.stdin.encoding говорит вам, что Python считает входным кодеком. Использование flags=re.UNICODE специально включает поддержку юникода в механизме регулярных выражений. И u'\W' дает движку строковый литерал Unicode; последнее является необязательным, но лучше быть явным.

Если вы хотите узнать больше о Unicode, закодированных байтовых строках и о том, как это связано с Python, я рекомендую вам прочитать:

person Martijn Pieters    schedule 19.12.2013

Вы можете заменить \W на [^\wåäö].

Однако тест text.isalnum вернет false, если строка содержит символ с диакритическим знаком.

person Casimir et Hippolyte    schedule 19.12.2013
comment
да, я попробовал это, и по какой-то глупой причине он все еще удаляет åäö :S - person A.collin; 19.12.2013
comment
@user2225454: Странно! Я протестировал его с помощью pythex.org, и, похоже, он работает. - person Casimir et Hippolyte; 19.12.2013
comment
Вы используете u'[^\wåäö]'? - person Eric; 19.12.2013
comment
u сообщает python Это последовательность кодовых точек юникода, а не последовательность байтов - person Eric; 19.12.2013
comment
Обратите внимание, что у вас все еще может быть плохое время - попробуйте на строке ääa - person Eric; 19.12.2013

Попробуйте использовать флаг re.UNICODE в re.sub()

person rook    schedule 19.12.2013