Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Perl: Общие вопросы > Сортировка русских имен в Perle


Автор: Суриец 23.4.2004, 09:27
Как отсортировать файл по полю, которое содержит фамилии на русском.
стандртно сортирует неправильно...
идет а,б,в,г... появляется Х... дальше правильно... потом опять Щ....

Как сделать?

Автор: ElectricalStorm 23.4.2004, 10:02
use Locale;

Автор: Суриец 23.4.2004, 10:56
Тоже самое выдает... так делал первоначально.

Автор: korob2001 23.4.2004, 18:00
Все работает.
Код

#!/usr/bin/perl -w
use strict;
use warnings;
use locale;
my @arr = qw(щ о п а в л д к ш з ф ц у б х с ч ы);
foreach my $letter ( sort { $a cmp $b } @arr ) {
   print $letter, "\n";
}

Автор: pych 26.4.2004, 07:27
Цитата(korob2001 @ 23.4.2004, 18:00)
Все работает.
Код

#!/usr/bin/perl -w
use strict;
use warnings;
use locale;
my @arr = qw(щ о п а в л д к ш з ф ц у б х с ч ы);
foreach my $letter ( sort { $a cmp $b } @arr ) {
   print $letter, "\n";
}


запустил твой скриптик у себя. результат:

а
б
ц
д
ф
х
к
л
о
п
с
у
в
ы
з
ш
щ
ч

результат запуска locale:

LANG=ru_RU.KOI8-R
LC_CTYPE="ru_RU.KOI8-R"
LC_NUMERIC="ru_RU.KOI8-R"
LC_TIME="ru_RU.KOI8-R"
LC_COLLATE=POSIX
LC_MONETARY="ru_RU.KOI8-R"
LC_MESSAGES="ru_RU.KOI8-R"
LC_PAPER="ru_RU.KOI8-R"
LC_NAME="ru_RU.KOI8-R"
LC_ADDRESS="ru_RU.KOI8-R"
LC_TELEPHONE="ru_RU.KOI8-R"
LC_MEASUREMENT="ru_RU.KOI8-R"
LC_IDENTIFICATION="ru_RU.KOI8-R"
LC_ALL=

где грабли??? sad.gif

ЗЫ. почему забанили сурийца?

Автор: Суриец 26.4.2004, 07:34
rolleyes.gif

Все ок... но осталась все тажа проблема.

Автор: korob2001 26.4.2004, 11:07
Цитата

запустил твой скриптик у себя. результат:

Странные вещи просходят. Какая у тебя версия Perl?

Автор: pych 26.4.2004, 11:24
This is perl, v5.6.1 built for i586-linux

Copyright 1987-2001, Larry Wall

Perl may be copied only under the terms of either the Artistic License or the
GNU General Public License, which may be found in the Perl 5 source kit.

Complete documentation for Perl, including FAQ lists, should be found on
this system using `man perl' or `perldoc perl'. If you have access to the
Internet, point your browser at http://www.perl.com/, the Perl Home Page.

Автор: HalkaR 26.4.2004, 23:31
Линуксовая версия, вполне возможно с кодовыми страницами проблемы.

Автор: Pattern® 27.4.2004, 01:41
В догонку данному сабжу. Была тут у меня примерно такая же задачка, отсортировать файл с фамилиями в алфавитном порядке. Каждая фамилия находится на одной строке. Вроде плёвая задачка. И я бы применил к ней то же sort { $a cmp $b } @arr. Да вот условие не очень привлекательное - не использовать ни одну встроенную функцию сортировки... butbut.gif adv/insane.gif Есть какие нить предложения?

Автор: Суриец 27.4.2004, 05:08
Цитата(HalkaR @ 26.4.2004, 23:31)
Линуксовая версия, вполне возможно с кодовыми страницами проблемы.

Как определить?? где можно взять нормальные кодовые страницы?

Автор: GoodBoy 27.4.2004, 10:21
2 Pattern® а в чем собссссна проблема?? Пузырек еще ни кто не отменял!!!! :-))))))

Автор: Pattern® 28.4.2004, 03:25
Цитата
- А нас в Кембридже учили после того, как сходишь в туалет, мыть руки...
- А в нашем институте не учили на руки писать..
(© Из анекдота)
2 GoodBoy ->Да дело то не в пузырьках (и не в их количестве, если кто то захочет добавить wink.gif ). А в том, что меня в институте учили "не изобретать велосипед дважды" (почему и привёл цитату из анекдота). А подобная задача меня просто выбила из колеи: почему встроенную функцию сортировки использовать нельзя, а остальные можно?

Автор: Pattern® 28.4.2004, 04:06
Цитата
Как определить?? где можно взять нормальные кодовые страницы?
Код
$koi_page_ = '\xE1\xE2\xF7\xE7\xE4\xE5\xB3\xF6\xFA\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF2\xF3\xF4\xF5\xE6\xE8\xE3\xFE\xFB\xFD\xFF\xF9\xF8\xFC\xE0\xF1\xC1\xC2\xD7\xC7\xC4\xC5\xA3\xD6\xDA\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD2\xD3\xD4\xD5\xC6\xC8\xC3\xDE\xDB\xDD\xDF\xD9\xD8\xDC\xC0\xD1';

$win_page_ = '\xC0\xC1\xC2\xC3\xC4\xC5\xa8\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF\xE0\xE1\xE2\xE3\xE4\xE5\xb8\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF';
2 Суриец -> Операция сортировки с помощью cmp происходит по возрастанию их ASCII-кода. Вот посмотри в какой последовательности идут кодовые страницы koi8-r и win-1251 ( от "А" до "Я" и от "а" до "я"). Теперь то понятно, почему "баги" вылезли?

Автор: Суриец 28.4.2004, 08:28
Pattern® , хочешь сказать, что никак не получится отсортировать??? Не верю... должен быть способ. Вот только какой...


Автор: GoodBoy 28.4.2004, 12:00
Цитата
Меня в институте учили "не изобретать велосипед дважды" (почему и привёл цитату из анекдота). А подобная задача меня просто выбила из колеи: почему встроенную функцию сортировки использовать нельзя, а остальные можно?

Мне как-то в универе на контрольной по ассембллеру снизили на 1 балл оценку за то, что я сделал инверсию числа путем вычитания его из нуля, а не использовал оператор NEG, который делает инверсию числа путем вычитания его из нуля... :-)))))))

Мораль: преподы та-а-а-а-акие загадашные, однако.... :-))))))))))

Автор: Суриец 30.4.2004, 05:55
И все таки... можно стандартными способами отсортировать правильно русские имена на Perle под Linux'ом.... ???
Или как-то надо извращаться? И как именно?

Автор: Pattern® 5.5.2004, 01:19
И что? В ответ тишина? butbut.gif
Суриец, я бы сделал это всё таким образом. Если у тебя система поддерживает koi8-r, то просто перед сортировкой массива взять и переконвертить искомый массив в win-1251, а после сортировки обратно его переконвертировать в koi8-r.
Вот тебе простейшие функции конвертации:
win-1251 в koi8-r
Код
sub wintokoi {
   my $decoderwin=shift;
   $decoderwin=~tr/\xC0\xC1\xC2\xC3\xC4\xC5\xa8\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF\xE0\xE1\xE2\xE3\xE4\xE5\xb8\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF/\xE1\xE2\xF7\xE7\xE4\xE5\xb3\xF6\xFA\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF2\xF3\xF4\xF5\xE6\xE8\xE3\xFE\xFB\xFD\xFF\xF9\xF8\xFC\xE0\xF1\xC1\xC2\xD7\xC7\xC4\xC5\\xa3\xD6\xDA\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD2\xD3\xD4\xD5\xC6\xC8\xC3\xDE\xDB\xDD\xDF\xD9\xD8\xDC\xC0\xD1/;
       return $decoderwin;
}
koi8-r в win1251
Код
sub koitowin {
   my $decoderwin=shift;
   $decoderwin=~tr/\xE1\xE2\xF7\xE7\xE4\xE5\xb3\xF6\xFA\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF2\xF3\xF4\xF5\xE6\xE8\xE3\xFE\xFB\xFD\xFF\xF9\xF8\xFC\xE0\xF1\xC1\xC2\xD7\xC7\xC4\xC5\\xa3\xD6\xDA\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD2\xD3\xD4\xD5\xC6\xC8\xC3\xDE\xDB\xDD\xDF\xD9\xD8\xDC\xC0\xD1/\xC0\xC1\xC2\xC3\xC4\xC5\xa8\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF\xE0\xE1\xE2\xE3\xE4\xE5\xb8\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF/;
       return $decoderwin;
}
ЗЫЖ Самый простой выход из положения и считается самым правильным... wink.gif

Автор: Суриец 5.5.2004, 11:06
О! biggrin.gif Все заработало!!! Огромное спасибо. cool.gif

Автор: YURIC 18.5.2004, 02:51
У меня вот так все отлично работает:

Код
#!/usr/bin/perl
use CGI::Carp qw/fatalsToBrowser/;
use locale;
use POSIX;
setlocale(LC_CTYPE,'ru_RU.CP1251');

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)