Perl и Unicode
Олег АлистратовPerl Mova – 2010
Зачем нужен Unicode?
Unicode в .ru
100 000 случайных сайтов Top 350* сайтов
72%
25%
1%2%
44%51%
2%3%
* По данным GoalEurope / Rating of Russian Web 2.0 Companies 2008
История
2000 2001 2002 2003 2004 2005 2006 2007 2008 20090%
10%
20%
30%
40%
50%
60%
70%
80%
90%
100%
KOI-8R
KOI-8R KOI-8R KOI-8R KOI-8RKOI-8R KOI-8R KOI-8R KOI-8R KOI-8R
windows-1251windows-1251windows-1251windows-1251windows-1251
windows-1251
windows-1251windows-1251
windows-1251windows-1251
UTF-8
UTF-8 UTF-8 UTF-8 UTF-8UTF-8
UTF-8UTF-8
UTF-8 UTF-8
Кодировка крупнейших сайтов в последние 10 лет
Трафик: text/plain
• Увеличение размера кириллического текста на 79%
Трафик: text/html
• Увеличение размера HTML с русским текстом на 14%
• Медианный размер 100 тыс. случайно выбранных русскоязычных страниц
Трафик: gzipped
0.001 0.5 1 1.5 2 2.5 3 3.5 4 4.5 5 5.5 6 6.5 7 7.5 8 8.5 9 9.50
2,000,000
4,000,000
6,000,000
8,000,000
10,000,000
12,000,000
14,000,000
16,000,000
UTF-8 Comress(UTF-8) windows-1251 Comress(windows-1251)
Количество символов, млн
Разм
ер, б
айт
Производительность: платформы
Mobile Intel® Celeron® 560 @ 2.13 GHz, RAM 1 GbMicrosoft® Windows® XP SP3ActiveState Perl v5.10.0
Intel® Core™2 Duo E7400 @ 2.80 GHz, RAM 2 GbUbuntu 9.10 Karmic Koala linux 2.6.31-14-serverperl v5.10.0
Intel® Xeon® E5450 @ 3.00 GHz × 2, RAM 32 GbFreeBSD® 6.2-RELEASE-p3perl v5.8.8
Строковые функции
length(…)
index(…)
substr(…)
107%
112%
105 … 172%
Регулярные выражения
/a/
/(.)\1/g
/[0-9]/
120 … 600%
115%
2100 ... 6500%
Регулярные выраженияuse re 'debug';
$a =~ /\d/;DIGIT
$a =~ /[0-9]/;ANYOF[0-9]
$a =~ /(?:0|1|2|3|4|5|6|7|8|9)/;TRIEC-EXACT[0-9]
Исходный файл в UTF-8{ use utf8; my $a = 'Привет!'; print length($a), "\n";}> 7
{ no utf8; my $a = 'Привет!'; print length($a), "\n";}> 13
Символы и байтыuse utf8; # or use encoding "cp1251";
my $a = 'Привет!';print length($a), "\n";
use bytes;print length($a), "\n";
> 7> 13
use encoding::warnings 'FATAL';
Исключения
• chdir, chmod, chown, chroot, exec, link, lstat, mkdir, rename, rmdir, stat, symlink, truncate, unlink, utime, -X
• %ENV• glob (<*>)• open, opendir, sysopen• qx/…/, system• readdir, readlink
Encodeuse utf8;use Encode;
my $x = 'a → b';$x = Encode::encode( 'windows-1251', $x, Encode::FB_HTMLCREF );print $x, "\n";
> a → b
Символыmy $copy = "\x00a9";
my $copy = "\x{00a9}";
my $copy = pack('U', 0x00a9);
print $copy;
> ©
Регулярные выраженияmy $copy = '©';
$copy =~ /\x{00a9}/;
$copy !~ /\p{Uppercase}/;
$copy =~ /\p{Other_Symbol}/;
$copy =~ /\p{InLatin-1_Supplement}/;
$copy !~ /\p{InCyrillic}/;
$copy !~ /\p{BidiClass:R}/;
IOopen(my $fh, "<:utf8", "file.txt");open(my $fh, "<:encoding(UTF-8)", "file.txt");
open(my $fh, "<:encoding(cp1251)", "file.txt");
binmode(STDOUT, ":utf8");
RTFM Encode::Supported
LWPuse LWP::UserAgent;
my $ua = LWP::UserAgent->new;
my $response = $ua->get("http://example.com");if ($response->is_success) { my $content = $response->decoded_content; if (defined($content)) { # ... }}
Базы данных
• MySQL$dbh->do('SET NAMES utf8');$dbh->{mysql_enable_utf8} = 1;
• PostgreSQL$dbh->do("SET client_encoding TO 'UTF8'");
$dbh->{pg_enable_utf8} = 1;
• SQLite$dbh->{sqlite_unicode} = 1;
Конвертация БД
• $ mysqldump db_name > dump.sql
• $ iconv -f cp1251 -t utf-8 dump.sql > newdump.sql
• $ sed -i .bak "s/cp1251/utf8/" newdump.sql
• $ mysql < newdump.sql
perl 5.12
• Расширена поддержка классов и свойста символов до стандартаUnicode 5.2.0
use charnames ':full';print "\N{GREEK SMALL LETTER ALPHA}"
Спасибо!
Олег Алистратовhttp://alienator.ya.ru
http://clubs.ya.ru/regexp/
Top Related