Уведомления

Группа в Telegram: @pythonsu

#1 Окт. 15, 2013 22:58:09

strider
Зарегистрирован: 2013-10-15
Сообщения: 3
Репутация: +  0  -
Профиль   Отправить e-mail  

re

Привет, программисты на python.
У меня вопрос по регулярным выражениям. Я не могу понять, почему не работает моё выражение:

>>> re.search('^[а-яa-z]+$', 'ыве', re.L | re.M)
>>>
Если убрать символ конца строки, выражение работает. Консоль работает в utf-8, соответственно, обе строки - и шаблон, и проверяемая строка - в этой кодировке.

Офлайн

#2 Окт. 15, 2013 23:45:59

JOHN_16
От: Россия, Петропавловск-Камчатск
Зарегистрирован: 2010-03-22
Сообщения: 3292
Репутация: +  221  -
Профиль   Отправить e-mail  

re

а у меня работает

>>> print re.search('^[а-яa-z]+$', 'ыве', re.L | re.M).group()
ыве



_________________________________________________________________________________
полезный блог о python john16blog.blogspot.com

Офлайн

#3 Окт. 16, 2013 00:01:26

Lexander
От:
Зарегистрирован: 2008-09-19
Сообщения: 1139
Репутация: +  33  -
Профиль   Отправить e-mail  

re

Какой версии питон?



Офлайн

#4 Окт. 16, 2013 03:59:32

bw
От:
Зарегистрирован: 2007-09-26
Сообщения: 938
Репутация: +  20  -
Профиль   Адрес электронной почты  

re

Да вроде как и не должно работать. Почему бы не использовать `unicode` вместо `str`? Я полагаю, что движку `re` насрать на то как ты себе представляешь строку, utf8, cp866, как-то ещё, он обрабатывает строку побайтно, а не посимвольно. Если бы `re.search` в качестве ещё одного аргумента принимала кодировку, то можно было бы надеяться, а так без вариантов.

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

..bw



Отредактировано bw (Окт. 16, 2013 04:00:09)

Офлайн

#5 Окт. 16, 2013 09:43:24

alrusdi
Зарегистрирован: 2013-09-30
Сообщения: 20
Репутация: +  8  -
Профиль   Отправить e-mail  

re

bw
Ну да, на 2x нужно изобретать что-то типа

print re.search(u'^[а-яa-z]+$', u'ыве', re.L | re.M).group()

Офлайн

#6 Окт. 16, 2013 15:07:42

strider
Зарегистрирован: 2013-10-15
Сообщения: 3
Репутация: +  0  -
Профиль   Отправить e-mail  

re

Спасибо за помощь. Python 2.7. А не расскажете, в двух словах, почему нужна такая магия?
P.S.

>>> print re.search('^[а-яa-z]+$', 'ыве', re.L | re.M).group()
Не сработает, так как search в этом случае возвращает None, у него нет метода group.

Офлайн

#7 Окт. 16, 2013 16:55:31

bw
От:
Зарегистрирован: 2007-09-26
Сообщения: 938
Репутация: +  20  -
Профиль   Адрес электронной почты  

re

Потому что u'' это строка `unicode`, это точно строка, а не набор байт, и каждый элемент представляет символ, а не половину как может быть в utf8. Для u'' уже не нужно указывать кодировку, кодировка только учитывается в момент компиляции. По возможности, лучше отдавать предпочтение `unicode`, в Python III вон вообще отменили обычные строки. `str` по сути это набор байт, как оно есть в Си и большинстве (если не во всех) других языков старше 10 лет. `unicode` внутрях интерпретатора представляется как ucs-2 или ucs-4.

..bw



Офлайн

#8 Окт. 18, 2013 13:24:45

strider
Зарегистрирован: 2013-10-15
Сообщения: 3
Репутация: +  0  -
Профиль   Отправить e-mail  

re

Спасибо за ответ. Я примерно представляю различия строк и принцип их работы в python3.
Я не могу понять, и мне интересно, почему указанное выражение не работает в python2.7. Обе строки - и шаблон, и проверяемая, указаны в одной кодировке, к тому же, я думал, re.L должен помогать работать с не-unicode.

Офлайн

#9 Окт. 18, 2013 21:21:45

bw
От:
Зарегистрирован: 2007-09-26
Сообщения: 938
Репутация: +  20  -
Профиль   Адрес электронной почты  

re

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



Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version