Показаны сообщения с ярлыком Perl. Показать все сообщения
Показаны сообщения с ярлыком Perl. Показать все сообщения

вторник, августа 04, 2009

Perl и преобразование регистра

Недавно хорошо промучился с преобразованием регистра в Perl. Дело в том,что Perl и Юникод не на короткой ноге, поэтому простым путём lc() ничего сразу не получится. Вот как следует преобразовывать в нижний регистр строку с Юникод-терминала:

#!/usr/bin/perl -w
use strict;
use Encode;
chomp(my $input = <STDIN>);
my $string = decode("UTF-8",$input);
$string = lc($string);
print encode("UTF-8",$string);

Я был удивлён,что совершенно не требуется прагма use locale. Наоборот, при её использовании всё только ухудшается.Также существуют функции decode_utf8 и encode_utf8, которые принимают только один параметр; работают аналогично.Юникод - двухбайтовая кодировка, и требует подобного обращения при любом использовании. В конце хочу добавить,что замечание интерпретатора "Wide character in print at ..." сигнализирует о том,что вы забыли закодировать строку обратно в UTF-8, и выводите её на экран во внутренней кодировке (попробуйте заменить последнюю строку на обычный print $string).

воскресенье, июня 28, 2009

Небольшой скрипт

Вчера была очередная игра, но я не об этом.
Я написал скрипт для того,чтобы обновлять внешний IP'шник в своём DC++. Предполагается linuxdcpp последних версий. Сильно, думаю, упростит жизнь людям с динамическим IP. Перед использованием проверьте переменные $path и $url

#!/usr/bin/perl
use strict;
use warnings;
use LWP::Simple; #получение IP
my $path = ".dc++/DCPlusPlus.xml";#местонахождение собственно конфига
my $url = "http://p2p.kuzbass.net/getip.php";#адрес, с которого берётся IP. Подойдёт любой стабильный и простой по выводу, как http://whatismyip.ru или http://whatismyip.org. Основной критерий, конечно же, стабильность.
my $ip = get($url) or die($!);
$ip =~ /(\d+.\d+.\d+.\d+)/; $ip = $1;
print "Your IP is: $1\n";
my $CONFIG, my $BACKUP;
open (CONFIG,$path) or die($!);
open (BACKUP,">",$path."~~") or die($!);
while (){
s{\d+.\d+.\d+.\d+}{$ip};
print BACKUP;
}
close(CONFIG);
close BACKUP;
exec ("mv $path~~ $path");

понедельник, апреля 20, 2009

Задачка на эзотерическое программирование

Что вернет следующее выражение:
1 ? 2 : 3 ? 4 : 5 ? 6 : 7 ? 8 : 9

Большая часть читателей, немного поразмыслив, ответит: 2.
И будет права.
Но весь трюк задачи в том,что правы они будут только наполовину.
Смотрите сами. Вот вывод на perl:
perl -e 'print 1 ? 2 : 3 ? 4 : 5 ? 6 : 7 ? 8 : 9;'
2

Вот вывод на php:
php -r 'echo 1 ? 2 : 3 ? 4 : 5 ? 6 : 7 ? 8 : 9;'
8


Объясняю, почему так. В большинстве языков (Perl, C, C++, Java, JavaScript, Ruby), эта конструкция читается по такому алгоритму: если верно 1, то выдать 2 - иначе вычислить остальное. В php выражение равносильно
(1 ? 2 : 3 ? 4 : 5 ? 6 : 7) ? 8 : 9

В чем и раскрывается его адская сущность.
Непонятно, почему создатели языка пошли этим странным путём, когда конструкция заимствована из Cи, но сам факт оставляет пищу для размышлений.
Огромное спасибо Shock! за идею.

вторник, марта 31, 2009

Регэкспы в Perl: секреты

Засел сегодня за perl, причём с твёрдым намерением разобраться в регэкспах.
Пока что сама программа продвигается медленно (хотя уже не выдаёт ошибок деления на 0), но я уже раскопал интересные секреты регэкспов Перла. Коими и спешу поделиться.
Информация редкая, такое не в каждом учебнике найдёшь.
КонструкцияЗначение
/xИнструкция в конце regexp'а разрешает использование разнообразных пробелов,а также комментов. ОЧЕНЬ РЕКОМЕНДУЮ к использованию: читабельность регэкспа повышается в разы, когда вы разбираете его по кусочкам.Естественно,что пробелы и "диезы" с использованием этого указания надо отделять слешем, если вы хотите их использовать по прямому назначению.
/mРассматривать переменную как многострочную. ^ и $ отвечают не за начало и конец строки,а за начало и конец любой строки параграфа.
/sРассматривать переменную как однострочную - . будет отвечать даже символу \n,который обычно она игнорирует.
(?#...)Помечает подстроку как коммент, в отличие от обычного #,который помечает весь остаток строки.Работает только при наличии инструкции /x.
?{CODE}Выполнить код внутри регэкспа (!!!). Код не интерполируется.
(*FAIL)Конструкция автоматически заставляет отвергнуть любые совпадения регэкспа.
(*ACCEPT)Обратно: автоматически утверждает совпадение регэкспа, дальше выражение не проверяется.
(*MARK:name)Ставит метку name в строке на текущей позиции
(*SKIP:name)отменяет все совпадения вплоть до метки name
\KНе учитывать текст,совпавший до этого,в результате регэкспа.


Многие из этого были введены именно в 5.10, поэтому не указаны даже в perlre.
Удачи в использовании!

Постоянные читатели

Архив