Титла: Perl регулярен израз Публикувано от: qwerty11 в Apr 12, 2012, 12:52 Здравейте, в момента ползвам един и същ Perl скрипт на няколко машини в къщи и на работа.Версията е This is perl, v5.10.1 (*) built for i486-linux-gnu-thread-multi
Тук всичко работи ОК. Този същия скрипт го качих на http://webzone.smshosting.bg като там версията ми показва че е This is perl, v5.8.8 built for x86_64-linux-thread-multi. Ето и скрипта: Код
целта е да стане това: 345 тетрадки 45 молива 110 райрани ризи И работи на perl, v5.10.1 Проблема се явява реда @FormToArray = split(/(?=\d+)/,$value); при версия perl, v5.8.8 на хостинга http://webzone.smshosting.bg и по-точно \d+ като на http://webzone.smshosting.bg въобще не зачита знака + и там се показва като 3 4 5 тетрадки 4 5 молива 1 1 0 райрани ризи Интересува ме версията ли на Perl прави проблем, и ако има друг начин по който да тръгне скрипта там. Няма да се обидя и ако някой коментира кода. Титла: Re: Perl регулярен израз Публикувано от: Demayl в Apr 12, 2012, 14:01 Код Това няма нужда. Виж това : Код
Титла: Re: Perl регулярен израз Публикувано от: qwerty11 в Apr 12, 2012, 15:56 Мерси The_Ghost
Твоя скрипт стана и между другото е доста симпатичен, ще го изплагиатствам за моите нужди. И все пак ме дразни защо Код в единия случай запазва разделителя, а на хостинга всяка цифра я шляпа като отделен елемент. Титла: Re: Perl регулярен израз Публикувано от: Naka в Apr 12, 2012, 15:57 (?=\d+) това е Lookahead.
Преди като си играх с Lookahead и Lookbehind - но не в перл а със pcre, имаше значение дали патъна който се гледа /напед или назад е с фиксирана дължина или е с променлива. При теб е с \d+ което не е фиксирсан стринг. Незнам дали е това проблема но имаше много разлики за интерпретирането на Lookahead/behind при отделните енджини за регулярни изрази. При пърл едно при java било друго, при pcre трето, Затова може да получваш различни резултати с различна версия на perl. Например pcre позволява променлива дължина на стринга при Lookahead и (?=\d+) би трябвало да е правилно и да работи. Но пък забранява всякъкви + * ? при Lookbehind ??? ??? ??? Може просто версията на перл да не подържа Lookahead с променлива дължина и затова + да се игнорира. пробвай да го сложиш в скоби (?=(\d+)) или пък търси друго решение без Lookahead/behind за да работи навсякъде. Титла: Re: Perl регулярен израз Публикувано от: Demayl в Apr 12, 2012, 18:00 Мерси The_Ghost Изплагиатствай го :D, иначе случая е както го описа Naka. Макар че ако не го поддържа ще гръмне. Рядко ползвам split, защото в повечето случаи с regex се вършат нещата. Макар че split-a е малко по-бърз, но ако го викнеш няколко пъти и regex-a става по бърз за дадено нещо. А и хубавото на perl е че всичко става по всякакъв начин :D Титла: Re: Perl регулярен израз Публикувано от: SmashThePain в May 31, 2012, 23:22 Сложни ungreedy операции не ти трябват в случая. Да не говорим, че стринга ако ти е на повече от един ред точката няма да мачне новия ред. Аз като цяло на ungreedy неща въобще не съм фен. Ungreedy е измислено с една основна цел. Да предотвратява убийствен backtracking в ала Perl енджини за регулярни изрази. За пример виж енджина на Томпсън дали ще намериш backtracking.
Няма да се отплесвам. Може да си опростиш израза с negation, ето така: Код: /(\d+)x([^\d]+)/g И "екс" - x е различно от буквата "х". Титла: Re: Perl регулярен израз Публикувано от: Demayl в Jun 01, 2012, 12:10 Сложни ungreedy операции не ти трябват в случая. Да не говорим, че стринга ако ти е на повече от един ред точката няма да мачне новия ред. Аз като цяло на ungreedy неща въобще не съм фен. Ungreedy е измислено с една основна цел. Да предотвратява убийствен backtracking в ала Perl енджини за регулярни изрази. За пример виж енджина на Томпсън дали ще намериш backtracking. Точно x си е буквата x, виж ако го напишеш \x за какво служи ( ако говориш за екс ). Да ако е на 2 реда примерно : 5 тет радки - няма да го хване, защото не това се търсеше . Идеята е че сигурно ако е на 2+ реда, значи нещо не е ок и едва ли ще е редно да се вземе. Backtrackinga на perl - мисля че е основната идея тук !? /(\d+)x([^\d]+)/g - вместо такъв negotation ( много тежък, може да пуснеш debug и да видиш ), може да е с \D+ . Иначе съм съгласен, че това е по-добрия вариант . Предишното така ми прещрака ;D Титла: Re: Perl регулярен израз Публикувано от: SmashThePain в Jun 01, 2012, 13:43 @The_Ghost тежко за какво, за компилиране или за изпълнение? И в двата случая:
Код
Няма никакъв backtracking и подозирам че времето за изпълнение ще са много близки. Аз лично предпочитам char class от гледна точка, че е лесно за добавяне на нови символи, но това са дреболии. За backtracking-а може да говорим много. Просто енджините ала Perl могат да имат катастрофален backtracking. Имат тъй наречените патологични изрази. Та ungreedy е пачване на по-голям backtracking. Само заради това писах в темата. Ако може да напишеш регулярен израз без backtracking и естествено без ungreedy нещата ще са доста по-добре. Също за оптимизации на Perl изрази е хубаво да се ползват atomic group и atomic repetition. Така например всеки лаик който пише: Код
И се чуди защо по дяволите му е бавен израза, ако го беше написал: Код
Щеше да разбере, че има backtracking от края на стринга обратно до `</head>`. Титла: Re: Perl регулярен израз Публикувано от: Demayl в Jun 01, 2012, 14:10 Ето ти резултат от (\D+) и ([^\d]+) s Benchmark модула -
\D+ - ~236000/s [^\d]+ - ~170000/s В случая [^\d]+ прави много повече стъпки. Иначе за примера е добре даден с .+ и .++ , по проста грешка която правят е с .* и .*? и се чудят защо не хваща първото срещнато след .* , а хваща последното. Не е катастрофален backtrackinga - просто хората го пишат така . |