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