информационная безопасность без паники и всерьез подробно о проекте |
||||||||||||||||||||||
|
||||||||||||||||||||||
|
12.03.16 19:00 // оригинал Чтобы набить руку, перетащил вспомогательные скрипты рабочего проекта с перла на питон. В процессе местами порадовался, местами исплевался. Некоторые вещи сперва привели в полное недоумение, окончательно с ними разобрался, пока писал этот поначалу еще более гневный пост, но даже после прояснения причины они оставили ощущение крайней неудовлетворенности и полной кривизны. Ну ладно, я смирился с тем, что raw strings не помогают в случае последнего '\' в строке (да, действительно, в такой строке может встретиться внутренний ', который нужно эскейпить, и различить две ситуации с \' невозможно). Смирился и с тем, что в подобной ситуации в случае регекспа один заменяемый слеш приходится изображать четырьмя. Но полной неожиданностью стало то, что та же фигня творится и со строкой замены, т.е. со вторым параметром sub. Т.е. вполне ожидаемо, что print (re.sub('a', '\n', 'a a a')) превратит три "а" в три перевода строки. Менее очевидно, но то же самое происходит при print (re.sub('a', r'\n', 'a a a')). По той же логике print (re.sub('a', '\\', 'a a a')) выдает ошибку и приходится использовать print (re.sub('a', '\\\\', 'a a a')). Похоже, что это сделали ради обработки всяких \1, из-за которых и строку замены стали обрабатывать аналогично шаблонной, другого объяснения я найти не могу. Что гораздо более неприятно, та же ерунда происходит, если эти слеши пришли в переменной, которая может использоваться и в других местах, где лишний слеш совсем ни к чему (какая-нибудь path = r'path\to\file', которая той же print выводится as is). И это уже заметно ломает поведение при переносе кода с перла - получается, что перед отправкой в регексп такую переменную нужно дополнительно обрабатывать. Причем re.escape тут, к сожалению, не помогает, поскольку портит другие символы. Небольшим утешением стало то, что подсовывание функции/лямбды ситуацию вроде бы лечит: print (re.sub('a', lambda m: '\\', 'a a a')), хоть возвращает она в точности ту же строку. --------------------- import re a = 'a a a' sl = '\\' n = r'\n' print (sl, n) print (1, re.sub('a', r'\n', a)) print (2, re.sub('a', '\n', a)) print (3, re.sub('a', n, a)) print (4, re.sub('a', lambda m: r'\n', a)) print (5, re.sub('a', lambda m: n, a)) print (6, re.sub('a', '\\\\', a)) print (7, re.sub('a', lambda m: '\\', a)) print (8, re.sub('a', lambda m: sl, a)) # print (re.sub('a', '\\', a)) # print (re.sub('a', sl, a)) --------------------- Аналогичный код на перле выдает вполне предсказуемый результат: $a = 'a a a'; $n = '\n'; $a =~ s/a/$n/g; print $a;
|
авто
венгрия
вырвиглаз
германия
глюки
греция
гуглемап
драйверы
египет
железки
журнализм
империя добра
испания
италия
кино
кипр
клоуны
книги
криворучки
оспорт
португалия
программизм
сайт
софт
стрим
студень
турция
уродцы
фото
франция
цацки
чехия
читалки
android
bq
e51
eeepc
from facebook
hd2
hpc
htc
ipad
iphone
onlime
vista
windows 10
windows 7
windows 8
yota
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
|
|
|