The OpenNET Project / Index page

[ новости /+++ | форум | wiki | теги | ]

форумы  помощь  поиск  регистрация  майллист  вход/выход  слежка  RSS
"regexp  + UTF-8 = не работает"
Вариант для распечатки  
Пред. тема | След. тема 
Форум Программирование под UNIX (Perl)
Изначальное сообщение [ Отслеживать ]

"regexp  + UTF-8 = не работает"  +/
Сообщение от Аноним (??) on 12-Мрт-09, 19:45 
Добрый день, уважаемые.

Подскажите пожалуйста почему Perl не парсит рег.выражения на русском вида [а-яА-Я] при использовании UTF8. Хотя с CP1251 проблем нет(если делаю iconv + использую setlocale(LC_CTYPE,"ru_RU.CP1251");

Имею:
$ locale
LANG=ru_RU.UTF-8
LC_CTYPE="ru_RU.UTF-8"
LC_NUMERIC="ru_RU.UTF-8"
LC_TIME="ru_RU.UTF-8"
LC_COLLATE="ru_RU.UTF-8"
LC_MONETARY="ru_RU.UTF-8"
LC_MESSAGES="ru_RU.UTF-8"
LC_PAPER="ru_RU.UTF-8"
LC_NAME="ru_RU.UTF-8"
LC_ADDRESS="ru_RU.UTF-8"
LC_TELEPHONE="ru_RU.UTF-8"
LC_MEASUREMENT="ru_RU.UTF-8"
LC_IDENTIFICATION="ru_RU.UTF-8"
LC_ALL=

Файл, к-ый хочу пропарсить имеет строки вида:
"Администратор" "Марфа Васильевна"
Естественно он сохранен в UTF-8

Мой скрипт:
#!/usr/bin/perl

use strict;
use warnings;

open(DATA,'file.txt');
my $infile = <DATA>;
close DATA;

while($infile =~ m/([А-Яа-я]+)/gi) {
        print "$1\n";
}

На выходе получаю:
$ perl report.pl
Админи


а
о
Ма

а
Ва
ил
евна

В чем трабла?
На википедии написано что с юникодом проблем не должно быть:
"Для использования последовательностей букв необходимо установить правильную кодовую страницу в которой эти последовательности будут идти в порядке от и до указанных символов. Для русского языка это Windows-1251, ISO 8859-5 и Юникод, так как в DOS-855, DOS-866 и KOI8-R русские буквы не идут одной целой группой или не упорядочены по алфавиту."

Ответить | Правка | Cообщить модератору

Оглавление

Сообщения по теме [Сортировка по времени | RSS]


1. "regexp  + UTF-8 = не работает"  +/
Сообщение от angra (ok) on 12-Мрт-09, 20:06 
man perluniintro
man perlunifaq
man perlunitut
man perlunicode
Можно начать с попытки добавлять
use utf8;
use open ':encoding(utf8)';
utf8::upgrade($infile);
Если не получится, то придется таки читать.
Ответить | Правка | ^ к родителю #0 | Наверх | Cообщить модератору

5. "regexp  + UTF-8 = не работает"  +/
Сообщение от Аноним но другой on 13-Мрт-09, 01:52 
>man perluniintro
>man perlunifaq
>man perlunitut
>man perlunicode
>Можно начать с попытки добавлять
>use utf8;
>use open ':encoding(utf8)';
>utf8::upgrade($infile);
>Если не получится, то придется таки читать.

Добавил, теперь скрипт выглядит так:
$ less report.pl
#!/usr/bin/perl

use utf8;
use open ':encoding(utf8)';
utf8::upgrade($infile);

open(DATA,'file.txt');
my $infile = <DATA>;
close DATA;

while($infile =~ m/([А-Яа-я]+)/gi) {
        print "$1\n";
}

$ less file.txt
"Администратор" "Марфа Васильевна"

$ ./report.pl
Wide character in print at page.analyser_simplified.pl line 12.
Администратор
Wide character in print at page.analyser_simplified.pl line 12.
Марфа
Wide character in print at page.analyser_simplified.pl line 12.
Васильевна

Работает!! Спасибо. Осталось теперь тока разобраться с руганью про wide character.
завтра почитаю. спасибо.

Ответить | Правка | ^ к родителю #1 | Наверх | Cообщить модератору

6. "regexp  + UTF-8 = не работает"  +/
Сообщение от angra (ok) on 13-Мрт-09, 02:14 
Ну не все же одновременно надо было добавлять. Кроме того utf8::upgrade($infile); перед использованием my $infile вообще не имеет смысла. Используйте use strict дабы избегать таких ошибок.
Попробуйте такой вариант:
#!/usr/bin/perl -w
use strict;

use utf8;

open(DATA,'file.txt');
my $infile = <DATA>;
utf8::decode($infile);
close DATA;

while($infile =~ m/([А-Яа-я]+)/gi) {
  my $s=$1;
  #нельзя напрямую применять encode к $1 иначе получим бред после первой строки
  utf8::encode($s);
  print "$s\n";
}

А вообще работа с юникодом в перле(да и в большинстве других языков) это шаманство, особенно когда много _различных_ потоков ввода/вывода.

Ответить | Правка | ^ к родителю #5 | Наверх | Cообщить модератору

2. "regexp  + UTF-8 = не работает"  +/
Сообщение от gaa (ok) on 12-Мрт-09, 21:46 
>Мой скрипт:
>#!/usr/bin/perl

В какой кодировке файл скрипта сохранён?

И обычно во всех регекспах есть спецпоследовательность для обозначения любого набора букв. Что-то вроде [[:alnum:]] или \w, уж не знаю как в перле.

Ответить | Правка | ^ к родителю #0 | Наверх | Cообщить модератору

3. "regexp  + UTF-8 = не работает"  +/
Сообщение от angra (ok) on 13-Мрт-09, 00:54 
>И обычно во всех регекспах есть спецпоследовательность для обозначения любого набора букв.
>Что-то вроде [[:alnum:]] или \w, уж не знаю как в перле.

Это по умолчанию только для английских, причем не только в перле. Кроме того в эти классы цифры тоже входят, а в \w еще и подчеркивание.
Перл позволяет работать с возможностями isalpha для локалей, в том числе и utf8, но для этого нужно явно указывать use locale.


Ответить | Правка | ^ к родителю #2 | Наверх | Cообщить модератору

4. "regexp  + UTF-8 = не работает"  +/
Сообщение от gaa (ok) on 13-Мрт-09, 01:25 
>>И обычно во всех регекспах есть спецпоследовательность для обозначения любого набора букв.
>>Что-то вроде [[:alnum:]] или \w, уж не знаю как в перле.
>Это по умолчанию только для английских, причем не только в перле.

В тикле под \w и [[:alpha:]] буквы из русской локали тоже подходят. Так что надо читать ман по конкретному языку.

Ответить | Правка | ^ к родителю #3 | Наверх | Cообщить модератору

7. "regexp  + UTF-8 = не работает"  +/
Сообщение от oklas (ok) on 03-Дек-13, 15:53 
В перле к строкам прикручены внутренние флаги, в частности есть флаг что строка во внутреннем формате, только с этим форматом нормально работают регулярные выражения и всякие там length и т.п.

Большинство проблем с кодировками можно решить придерживаясь например такой схемы работы:

use utf8; # предписывает что константы и регулярные выражения, имеющие не-ASCII символы,
должны трактоваться как уникодные и приводиться ко внутреннему формату

use Encode; # включаем модуль работы с кодировками.

$bytes = encode('utf-8', $string); # в байты, (из внутреннего формата)
$string = decode('utf-8', $bytes); # преобразовать во внутренний формат

! ВАЖНО, если perl собран и операционная система настроена так, что внутреннее представление переменных в utf-8 и print'ы и прочее выводят в utf-8, то это не значит что не надо пропускать через decode( 'utf-8', ... ), строки пришедшие откуда-то (из socket'а или fcgi, или модуля какого-нибудь и т.п.) то что строка в utf-8 еще не значит что она во внутреннем формате.

При работе с файлами можно использовать специальный синтаксис при открытии:

open FH, "<:utf8", $filename; # подробнее "perldoc -f open"

Ответить | Правка | ^ к родителю #0 | Наверх | Cообщить модератору

8. "regexp  + UTF-8 = не работает"  +/
Сообщение от Анатолий email(??) on 21-Авг-14, 09:38 
>[оверквотинг удален]
> $bytes = encode('utf-8', $string); # в байты, (из внутреннего формата)
> $string = decode('utf-8', $bytes); # преобразовать во внутренний формат
> ! ВАЖНО, если perl собран и операционная система настроена так, что внутреннее
> представление переменных в utf-8 и print'ы и прочее выводят в utf-8,
> то это не значит что не надо пропускать через decode( 'utf-8',
> ... ), строки пришедшие откуда-то (из socket'а или fcgi, или модуля
> какого-нибудь и т.п.) то что строка в utf-8 еще не значит
> что она во внутреннем формате.
> При работе с файлами можно использовать специальный синтаксис при открытии:
> open FH, "<:utf8", $filename; # подробнее "perldoc -f open"

Мне странно читать подобные недовольсва... некоторые абсолютно уверены, что это какая-то ошибка и потому не рабоате! Нет граждане непонимающие это не ошибка... И оно не должно работать Просто потому что всё это работает через ctype функции... А  они не работают с мультибайтовыми кодировками! Ещё более странно даже не это, а то, что люди с таким упрорством пытаются использовать самую неудобную и самую тормознутую из всех кодировок utf8... Я не знаю ни одного приложения где такая кодировка действительно нужна. За исключением разве что языков с очень большим числом иероглифов как в китайском... Но мы же не китайцы!!!  В большинстве приложений хватает ASCII кодировок и это разумно использовать именно их! Но если вам не хватает симоволв или надо одновременно более 2-х языков сразу(в вебе к примеру...) то используйте вы Unicode. Это на порядок проще и быстрее!!! И там всё рабоатет. Функции другие, н отак всё тоже самое... Открою вам секрет, UTF8 это не ASCII кодировка и не Unicode.. Это мудьтибайтовая кодировка... И отсюда все беды! Никогда её не используйте и у вас не будет проблем. Перекодировать строку из utf8 в любую другую очень прсото с помощью стандартной функции iconv.

Ответить | Правка | ^ к родителю #7 | Наверх | Cообщить модератору

10. "regexp  + UTF-8 = не работает"  +/
Сообщение от oklas (ok) on 21-Авг-14, 10:53 
- никаких проблем с использовнием utf8 в перл не возникает,
  и в частности в связи с тем что кодировка мультибайтовая.

- тормознутой кодировка быть не может, могут быть тормознутыми
  алгоритмы (работающие с данными в разных кодировках).

- на этапе обучения всегда бывают вопросы, здесь и есть их место.

- если есть данные о несоответствии поведения перл описанному
  в документации пишите разработчикам перл.

- "люди с таким упрорством пытаются использовать" - это вы видимо
  про разработчиков таких систем как google yandex rambler и т.д.

Ответить | Правка | ^ к родителю #8 | Наверх | Cообщить модератору

9. "regexp  + UTF-8 = не работает"  +/
Сообщение от Анатолий email(??) on 21-Авг-14, 09:47 
А вы не пробовали задать другую локаль к примеру вызвав функцию setlocale? И у вас сразу всё станет настроено на другой язык и другую кодировку.. Так же легко перестроить среду с которой вы работаете, к примеру редактор, сообщения об ошибках и т.п.  Да хоть всю систему если надо... Если у вас нет соотвствующей локализации для perl а ид программ, то их легко скачать с интернета и установить!!! Это же свободное ПО и там есть все мыслимые и немыслимые локализации!!! Ну в крайнем случае можете написать свою... Но нафига, если есть готовая!
Ответить | Правка | ^ к родителю #7 | Наверх | Cообщить модератору

Архив | Удалить

Рекомендовать для помещения в FAQ | Индекс форумов | Темы | Пред. тема | След. тема




Спонсоры:
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2021 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру