Как стать автором
Обновить

Комментарии 20

Полезная шпаргалка. В избранное :)

Вот кто бы ещё написал про оптимизацию питоньих регэкспов — вообще бы было здорово.

От себя замечу:
— встроенные в питон регэкспы написаны на самом питоне и не слишком быстрЫ
— в отличие от «обычного» кода их нельзя ускорить при помощи psyco
— по моим тестам обработка не слишком больших (до 2мб, книжки с самиздата) текстов «руками» давала ускорение от 1.5 до 6 раз.
Встроенные в питон регэкспы написаны на C, и ненамного медленнее перловых, а изредка и быстрее.

Modules/_sre.c
Согласен, об этом сказано и в первой половине пособия.
Хм… Заставили зарыться в исходники…

Таки да, исполняющая часть «живёт» в статически скомпиленном модуле _sre, а все 50кб кода из sre_*.py в основном всяческие обёртки…

Эхх… Значит не видать мне 100500 раз ускорения от подключения внешней библиотеки :(
Остаётся вопрос про оптимизацию самих регэкспов, типа «Как писать быстрые регулярные выражения». Нет на примете подобной статьи? Почитал бы не без удовольствия ;)
Очень неплохие примеры, руководство написано длинновато, но все по делу.
Хорошо, что даны строковые методы, их надо бы выделить в отдельную главу Оптимизация.
Всмысле строковые методы? О них здесь говорится как пример того, когда не нужно изобретать велосипед с регулярными выражениями. Длинновато, потому что это почти полный перевод.
«Велосипед» — это немного другое, ведь чтобы его не изобретать, надо знать. Поэтому само Ваше руководство целиком (перевод) работает на это.
А пункт о строковых методах показывает часть ограничений для регулярных выражений. Иначе говоря, нужны правильные методы для соответствующих задач. Не надо рассчитывать на широкий универсализм регэкспов.
я читаю такие штуки когда надо ими пользоваться, а так, прочитал забыл.
Просто интервал времени, определенный вами как «когда надо пользоваться» может растянуться на продолжительный срок.
— братан, я не ел три дня!
— Как не ел? надо заставлять себя!

Обычно новые технологии всегда кажется неуместно обкатывать, то времени нет, то возможности, то не понимаешь, как применить, если работу надо сделать в excel и даже кажется, что регулярки подойдут, но как их применить? Хорошо бы автор топика ещё и показал, как ими воспользоваться, когда пользователь работает в среде где использование регулярок в принципе не предусмотрено. Хотя бы несколько ухищрений. Без них никуда ;)
Спасибо за перевод.

Только «опережающая и ретроспективная позиционная проверка», знакомая по книге Фридла, мне кажется, звучит лучше, чем «положительное и отрицательное утверждение предпросмотра»
Спасибо, я не очень знаком с этими терминами и во многих «длинных» словосочетаниях было непросто подобрать достойный эквивалент.
negative lookahead и positive/negative lookbehind — это совсем разные вещи.
про последние ("(?<=expr)", "(?<!expr)"), кстати, вообще не упомянуто.
RegexBuddy упомяните, пожалуйста, в статье — архиполезный инструмент в этом деле.
НЛО прилетело и опубликовало эту надпись здесь
Expresso заточен под синтаксис регулярок .NET, синтаксисы, конечно, оень похожи между собой, но для нормального применения Expresso нужно держать разницу в голове, что для новичка может оказаться неподъемно.
В идеале можно начать триала RegexBuddy, подтянуть хотя бы немного понимание регулярок, после чего попробовать перейти на Expresso
Для закрепления всего могу подкинуть очень хорошую задачку на регулярные выражения — разбить одним выражением число на триады: 1234567 станет 1.234.567

А для себя в качестве упражнения как-то написал galaxy почти полностью на рэгэкспах. perl использовал только как средство ввода-вывода. Вся логика в регэкспах.
q — влево, w — вправо, проблел — стрелять. Есть один баг со смещением кораблей, но было лениво фиксить.

Вот код
#!/usr/bin/perl                                                                                                                                                                                                                                                                
use strict;                                                                                                                                                                                                                                                                    
use warnings;                                                                                                                                                                                                                                                                  
use Time::HiRes qw(usleep);                                                                                                                                                                                                                                                    
use Term::ReadKey;                                                                                                                                                                                                                                                             
                                                                                                                                                                                                                                                                               
$_ = "\33[2J\x33[HD<\n\33[2J\33[H+"."-" x 40 . "+\n|" . (" " x 10 . "x " x                                                                                                                                                                                                     
     10 . " " x 10 . "|\n|") x 5 . (" " x 40 . "|\n|") x 10 . " " x                                                                                                                                                                                                            
     19 . "^" . " " x 20 . "|\n+" . ("-" x 40) . "+";                                                                                                                                                                                                                          
my $i = 0;                                                                                                                                                                                                                                                                     
while ( 1 ) {                                                                                                                                                                                                                                                                  
        s/^([^\n]+)\n(.*)/$2\n$1/s;                                                                                                                                                                                                                                            
        if ( $i == 5 ) {                                                                                                                                                                                                                                                       
        s/(.*?) x(?=.*?D<)/$1X /sg;                                                                                                                                                                                                                                            
        s/(.*?)x (?=.*?D>)/$1 X/sg;                                                                                                                                                                                                                                            
        s/(\|X.*)D</$1Dv>/s;                                                                                                                                                                                                                                                   
        s/(X\|.*)D>/$1Dv</s;                                                                                                                                                                                                                                                   
        s/(?<=\-.{42})\./ /sg;                                                                                                                                                                                                                                                 
        s/X(.{42})\./ $1 /sg;                                                                                                                                                                                                                                                  
        s/X\./  /sg;                                                                                                                                                                                                                                                           
        s/\.X/  /sg;                                                                                                                                                                                                                                                           
        s/(?<=X.{42}) (?=.*Dv)/*/sg;                                                                                                                                                                                                                                           
        s/X(?=.{42}\*.*Dv)/ /sg;                                                                                                                                                                                                                                               
        s/(?<=X.{42}) (?=.*Dv)/*/sg;                                                                                                                                                                                                                                           
        s/X(?=.{42}\*.*Dv)/ /sg;                                                                                                                                                                                                                                               
        s/(?<=X.{42}) (?=.*Dv)/*/sg;                                                                                                                                                                                                                                           
        s/X(?=.{42}\*.*Dv)/ /sg;                                                                                                                                                                                                                                               
        s/(?<=X.{42}) (?=.*Dv)/*/sg;                                                                                                                                                                                                                                           
        s/X(?=.{42}\*.*Dv)/ /sg;                                                                                                                                                                                                                                               
        s/(?<=X.{42}) (?=.*Dv)/*/sg;                                                                                                                                                                                                                                           
        s/X(?=.{42}\*.*Dv)/ /sg;                                                                                                                                                                                                                                               
        s/\*/X/sg;                                                                                                                                                                                                                                                             
        s/Dv</D</s;                                                                                                                                                                                                                                                            
        s/Dv>/D>/s;                                                                                                                                                                                                                                                            
        s/.*?X[^\n]+\n\| *\^.*/"\33[2J\33[HGame over"/es;                                                                                                                                                                                                                      
        s/X/x/g;                                                                                                                                                                                                                                                               
        }                                                                                                                                                                                                                                                                      
        s/(.*)\n([^\n]+)$/$2\n$1/s;                                                                                                                                                                                                                                            
        s/ (.{42})\./\.$1 /sg;                                                                                                                                                                                                                                                 
        ReadMode 4;                                                                                                                                                                                                                                                            
        my $key;                                                                                                                                                                                                                                                               
        $key = ReadKey(-1);                                                                                                                                                                                                                                                    
        if ( defined $key ) {                                                                                                                                                                                                                                                  
                s/ (?=.{42}\^)/./sg if $key eq ' ';                                                                                                                                                                                                                            
                s/\^ / ^/sg if $key eq 'w';                                                                                                                                                                                                                                    
                s/ \^/^ /sg if $key eq 'q';                                                                                                                                                                                                                                    
        }                                                                                                                                                                                                                                                                      
        ReadMode 0;                                                                                                                                                                                                                                                            
        print $_,"\n";                                                                                                                                                                                                                                                         
        s/Game over/exit()/e;                                                                                                                                                                                                                                                  
        $i = 0 if $i++ == 5;                                                                                                                                                                                                                                                   
        usleep (20000);                                                                                                                                                                                                                                                        
}
Для закрепления всего могу подкинуть очень хорошую задачку на регулярные выражения — разбить одним выражением число на триады: 1234567 станет 1.234.567

f = lambda s: re.sub(r"(\b|\d)(\d+?)(?=(?:\d{3,3})+?\b)", r"\1\2.", s)

Наверняка можно проще, но у меня получилось только так :(
Могу я попиариться предложить дополнить заметку ссылкой на мой гайд по регулярным выражениям? eax.me/regular-expr/
Да заметка уже переросла возможности храбра по объему текста. А guide очень даже ничего. Плюс вам.
Зарегистрируйтесь на Хабре , чтобы оставить комментарий

Публикации

Истории