Необработанные строки Python и Unicode: как использовать веб-ввод в качестве шаблонов регулярных выражений?
РЕДАКТИРОВАТЬ: Этот вопрос не имеет смысла, как только вы поймете, что означает флаг "r". Подробнее здесь. Для людей, которые ищут быстрый ответ, я добавил ниже.
Если я ввожу регулярное выражение вручную в скрипте Python, я могу использовать 4 комбинации флагов для моих строк шаблона:
- p1 = "образец"
- p2 = u "шаблон"
- p3 = r "шаблон"
- p4 = ru "шаблон"
У меня есть куча строк Unicode, поступающих из веб-формы ввода, и я хочу использовать их в качестве шаблонов регулярных выражений.
Я хочу знать, какой процесс я должен применить к строкам, чтобы я мог ожидать аналогичного результата от использования формы, приведенной выше. Что-то вроде:
import re
assert re.match(p1, some_text) == re.match(someProcess1(web_input), some_text)
assert re.match(p2, some_text) == re.match(someProcess2(web_input), some_text)
assert re.match(p3, some_text) == re.match(someProcess3(web_input), some_text)
assert re.match(p4, some_text) == re.match(someProcess4(web_input), some_text)
Что было бы от какого-нибудь Process1 до someProcessN и почему?
Я полагаю, что someProcess2 не нужно ничего делать, в то время как someProcess1 должен выполнить некоторое преобразование Unicode в локальную кодировку. Что касается необработанных строковых литералов, я ничего не понимаю.
3 ответа
Помимо возможного правильного кодирования Unicode (в Python 2.*), не требуется никакой обработки, потому что нет определенного типа для "сырых строк" - это просто синтаксис для литералов, то есть для строковых констант, и вы не У вас есть строковые константы в вашем фрагменте кода, поэтому "обрабатывать" нечего.
Флаги "r" просто не позволяют Python интерпретировать "\" в строке. Поскольку Интернет не заботится о том, какие данные он несет, ваш веб-ввод будет состоять из нескольких байтов, которые вы можете интерпретировать так, как хотите.
Итак, чтобы решить эту проблему:
- убедитесь, что вы используете Unicode (например, UTF-8) на протяжении всего пути
- когда вы получите строку, это будет Unicode, а "\ n", "\ t" и "\ a" будут литералами, поэтому вам не нужно заботиться о том, нужно ли их избегать.
Обратите внимание на следующее в вашем первом примере:
>>> p1 = "pattern"
>>> p2 = u"pattern"
>>> p3 = r"pattern"
>>> p4 = ur"pattern" # it's ur"", not ru"" btw
>>> p1 == p2 == p3 == p4
True
Хотя эти конструкции выглядят по-разному, все они делают одно и то же, они создают строковый объект (p1 и p3 a str
и р2 и р4 а unicode
объект в Python 2.x), содержащий значениеpattern
". u
, r
а также ur
просто скажите парсеру, как интерпретировать следующую строку в кавычках, а именно как текст в юникоде (u
) и / или необработанный текст (r
), где обратная косая черта для кодирования других символов игнорируется. Однако, в конце концов, не имеет значения, как была создана строка, является ли она необработанной строкой или нет, внутри она сохраняется одинаково.
Когда вы получаете Unicode текст в качестве ввода, вы должны отличаться (в Python 2.x), если это unicode
текст или str
объект. Если вы хотите работать с контентом Unicode, вы должны внутренне работать только с ними и конвертировать все str
возражает против unicode
объекты (либо с str.decode()
или с u'text'
синтаксис для жестко закодированных текстов). Однако если вы закодируете его в локальную кодировку, у вас возникнут проблемы с символами Юникода.
Другой подход будет использовать Python 3, который str
Объект поддерживает Unicode напрямую и хранит все как Unicode и там, где вам просто не нужно заботиться о кодировке.