Найти - Пользователи
Полная версия: re
Начало » Python для новичков » re
1
strider
Привет, программисты на python.
У меня вопрос по регулярным выражениям. Я не могу понять, почему не работает моё выражение:
>>> re.search('^[а-яa-z]+$', 'ыве', re.L | re.M)
>>>
Если убрать символ конца строки, выражение работает. Консоль работает в utf-8, соответственно, обе строки - и шаблон, и проверяемая строка - в этой кодировке.
JOHN_16
а у меня работает
>>> print re.search('^[а-яa-z]+$', 'ыве', re.L | re.M).group()
ыве
Lexander
Какой версии питон?
bw
Да вроде как и не должно работать. Почему бы не использовать `unicode` вместо `str`? Я полагаю, что движку `re` насрать на то как ты себе представляешь строку, utf8, cp866, как-то ещё, он обрабатывает строку побайтно, а не посимвольно. Если бы `re.search` в качестве ещё одного аргумента принимала кодировку, то можно было бы надеяться, а так без вариантов.

p.s. Речь о Python II, если что.

..bw
alrusdi
bw
Ну да, на 2x нужно изобретать что-то типа
print re.search(u'^[а-яa-z]+$', u'ыве', re.L | re.M).group()
strider
Спасибо за помощь. Python 2.7. А не расскажете, в двух словах, почему нужна такая магия?
P.S.
>>> print re.search('^[а-яa-z]+$', 'ыве', re.L | re.M).group()
Не сработает, так как search в этом случае возвращает None, у него нет метода group.
bw
Потому что u'' это строка `unicode`, это точно строка, а не набор байт, и каждый элемент представляет символ, а не половину как может быть в utf8. Для u'' уже не нужно указывать кодировку, кодировка только учитывается в момент компиляции. По возможности, лучше отдавать предпочтение `unicode`, в Python III вон вообще отменили обычные строки. `str` по сути это набор байт, как оно есть в Си и большинстве (если не во всех) других языков старше 10 лет. `unicode` внутрях интерпретатора представляется как ucs-2 или ucs-4.

..bw
strider
Спасибо за ответ. Я примерно представляю различия строк и принцип их работы в python3.
Я не могу понять, и мне интересно, почему указанное выражение не работает в python2.7. Обе строки - и шаблон, и проверяемая, указаны в одной кодировке, к тому же, я думал, re.L должен помогать работать с не-unicode.
bw
utf-8 не фиксированной же длинны. Как `re` поймёт что ему нужно то из одного, то из четырёх байт формировать символ. Очевидно никак, не предусмотрено, это естественный вывод из API так как кодировка нигде не передается в функциях. Вот что видит `re.search`:
>>> '^[а-яa-z]+$'
'^[\xd0\xb0-\xd1\x8fa-z]+$'
>>> len(_)
13
>>> 'ыве'
'\xd1\x8b\xd0\xb2\xd0\xb5'
>>> len(_)
6
Что находится в `str` и в какой кодировке знает только программист, может там текст библии на арамейском, а может прон-картинка какая-нибудь. Если API сложнее чем сравнение и сортировка, то для нормальной работы со строками ему требуется знать кодировку (она как-то должна передаваться в функцию), т.е. же `str.lower` и `str.upper` не всегда будут работать как ты ожидаешь.

..bw
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB