Я получил строку, и я хочу, чтобы re.sub
эту строку в Python2, поэтому я попробовал следующий оператор, он работал
>>> import re
>>> re.sub(u"[]", "", u"abc")
'abc'
Но когда я попробовал следующий оператор, он просто не удался как для Windows 10 (Python 2.7.15 | Anaconda, Inc. | (по умолчанию, 1 мая 2018, 18:37:09) [MSC v.1500 64 бит (AMD64)] на win32).
>>> re.sub(ur"[\u2122\u00ae]", "", u"abc")
u'a?b?c'
Я пробовал решение из Python и регулярного выражения с помощью Unicode, но он не работал ни с одним из них.
>>> myre = re.compile(ur'[\u2122\u00ae]', re.UNICODE)
>>> print myre.sub('', u"abc")
Так почему это происходит и как я могу это исправить?
У вас здесь две проблемы.
Во-первых, весь смысл строковых литералов-строк заключается в том, что они не рассматривают escape-обратные экраны как escape-обратные следы. Итак, ur"[\u2122\u00ae]"
буквально являются символами [
, \
, u
, 2
, 1
и т.д.
В Python 3 это прекрасно, потому что модуль re
понимает \u
escape-символы, что означает символы Unicode, поэтому шаблон заканчивается тем, что он является символьным классом с U+2122
и U+00AE
в нем, точно так, как вы хотите. Но в Python 2 это не так, поэтому класс персонажей оказывается бесполезным бесполезным барахлом.
Если вы измените его, чтобы использовать u"[\u2122\u00ae]"
строковый литерал, это решит эту проблему: u"[\u2122\u00ae]"
. Конечно, это вызовет все другие потенциальные проблемы, из-за которых люди хотят использовать сырые строковые литералы, в первую очередь с регулярными выражениями, но, к счастью, у вас их нет.
Вторая проблема заключается в том, что вы используете символы Unicode в литералах Unicode без объявления кодировки. Опять же, не проблема в Python 3, но она находится в Python 2.
Когда вы вводите "abc"
, есть хороший шанс, что вы на самом деле не \u2122
Python не \u2122
, а \u0099
. Вероятно, ваша консоль похожа на cp1252, поэтому, когда вы вводите или вставляете a , то, что на самом деле дает Python, это U + 0099, а не U + 2122. Конечно, ваша консоль также неправильно отображает вещи, так что
U+0099
заканчивается так же, как и . Но Python не знает, что происходит. Он просто видит, что U + 0099 не тот же символ, что и U + 2122, и поэтому нет совпадения. (Ваш первый пример работает, потому что ваша строка поиска также имеет неправильный
\u0099
, так что это происходит, чтобы соответствовать.)
В исходном коде вы можете исправить это, добавив объявление кодировки, чтобы сообщить Python, что вы используете cp1252, или указав редактору использовать UTF-8 вместо cp1252. Но в интерактивном интерпретаторе вы получаете любую кодировку, требуемую вашей консолью, и негде было бы поместить объявление кодирования.
На самом деле нет хорошего решения.
Ну, есть: обновление до Python 3. Основная причина, по которой он существует, заключается в том, чтобы сделать головные боли Unicode такими, как это происходит, и Python 2 меньше, чем полтора года с конца жизни, так что вы действительно хотите узнать, как бороться с головными болями Юникода в Python 2 сегодня?
Вы также можете получить терминал UTF-8 (и тот, который Python распознает как таковой). Это автоматическое определение на macOS или последних Linux-дистрибутивах; на Windows это намного сложнее, и, вероятно, не так, как вы хотите пойти сюда.
Таким образом, единственной альтернативой является просто никогда не использовать символы Unicode в литералах Unicode в интерактивном интерпретаторе. Опять же, вы можете использовать их в исходном коде, но в интерактивном режиме вы должны:
Я не уверен, действительно ли "abc".decode('cp1252')
лучше, чем \u
экранов, но он будет работать.
u"[\u0099\u2122]"
чтобы посмотреть, сможет ли Python идентифицировать метку ™
если консоль u"[\u0099\u2122]"
некоторую неверную интерпретацию, и в результате будет показано, что Python по-прежнему не может соответствовать, возможно, это потому, что моя консоль по умолчанию это ANSI? В целом, я думаю, что вы правы, использование Python 2 является самой проблемой.
Просто удалите r
перед строкой, и она работает:
re.sub(u"[\u2122\u00ae]", "", u"abc")
Python 2.7.15 |Anaconda, Inc.| (default, May 1 2018, 18:37:09) [MSC v.1500 64 bit (AMD64)] on win32
. Это печатает u'a?b?c'
u"ab®c"
8-битную строку""
в строку Unicodeu"ab®c"
. Чтобы сделать это, Python должен угадать, хотите ли вы кодировать один или декодировать другой, и, даже если это окажется правильным, вы все еще полагаетесь на что-то неочевидное и делаете свой код немного медленнее, без веской причины.u''
использовать