Модераторы: korob2001, ginnie
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> perl JSON кодировка 2 
:(
    Опции темы
mastercz
Дата 6.11.2009, 18:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 112
Регистрация: 5.11.2008

Репутация: нет
Всего: нет



В предыдущей теме были раскрыты все возникшие на тот момент вопросы и найдено решение, однако несколько позже на этапе эксплуатации возникло некоторая неудовлетворенность полученным результатам. Позволю себе задать еще пару вопросов по этой теме.

1. Json::XS парсирует JSON обратно в перл в кодировке UTF-8, хотя как я понимаю на JSON не накладывается ограничение на кодировку. Существует ли модуль JSON работающий с восмибитными кодировками.  JSON::Syck вроди-бы как позволяет работать с восмибитными кодировками, но насколько качественный.

2. Для передачи нескольких переменных в одной конечно  использовать простую обертку с экранированием управляющих символов в названиях и потом разворачивать по уникальным двойным символам (например' ==', если в названиях и данных символ '=' заменяться например на '/='). Однако хотелось бы применять JSON , как более стандартный контейнер, с которым можно работать стандартными функциями JavaScript фреймворков. Возможно ли как-нибудь реализовать собственную функцию для распарсивания хотя бы JSON объекта, представляющего собой простой хэш массив. Мне это представляется весьма сложной задачей, однако возможно я ошибаюсь ?

3. И третий последний вопрос. JSON::XS позволяет формировать JSON и в восьмибитной кодировке, однако при декодировании данные строки должны быть UTF8 для правильного декодирование. Т.К. JSON формат это переменная типа SCALAR, то если, я буду преобразовывать из koi8-r в UTF8  уже готовую строку, а не  переменные на входе преобразования в JSON, это недолжно вызвать каких либо ошибок ?

Заранее благодарен за помощь. 

К сожалению использовать UTF8  не оптимальное решение, так как скрипт реализован на koi8-r  и при использовании UTF8 придется много изменять. Хранение же переменных utf8 на странице  koi8-r не думаю что правильно и лишено всяких глюков.
 
PM MAIL   Вверх
DurRandir
Дата 9.11.2009, 14:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 335
Регистрация: 27.9.2009

Репутация: 14
Всего: 17



1+3 решается использованием JSON::XS + iconv: 
iconv('utf-8', 'koi8-r', encode_json $object)

Декодирование - в обратном порядке. По подводным камням восприятия JSON в javasctipt - смотрите http://search.cpan.org/~mlehmann/JSON-XS-2..._and_ECMAscript
PM   Вверх
sir_nuf_nuf
Дата 10.11.2009, 13:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 920
Регистрация: 6.1.2008

Репутация: 14
Всего: 31



Цитата(mastercz @  6.11.2009,  18:44 Найти цитируемый пост)
как я понимаю на JSON не накладывается ограничение на кодировку

Накладывает - только UTF8.

Цитата(mastercz @  6.11.2009,  18:44 Найти цитируемый пост)
Json::XS парсирует JSON обратно в перл в кодировке UTF-8

JSON::XS предполагает, что данные в json - в кодировке utf8 - и тупо втягивает их в perl.
Потом ставит на них флаг UTF8 в перле.

Если у вас есть "как бы JSON", в котором данные в CP1251, то вы можете распарсить их JSON::XS, а потом просто снять флаг UTF8 с помощью utf8::downgrade в perl. Я так и делал.


Цитата(mastercz @  6.11.2009,  18:44 Найти цитируемый пост)
Возможно ли как-нибудь реализовать собственную функцию для распарсивания хотя бы JSON объекта, представляющего собой простой хэш массив.

Возможно. Но зачем? есть же JSON::XS.  Но на выходе вы получите не объект, а простой хэш,
Хотя, если мне не изменяет память - в JSON::XS есть какой-то хук, для того что при парсинге делать bless.
Однако, заметьте JSON - предназначен для передачи данных, а не объектов - вот и используйте его по назначению.

3. попробуйте сделать обратную процедуру, сначала uft::upgrade на строку в кодировке (например koi8-r), а потом ее кодировать.. однако не факт что это сработает.


--------------------
user posted image
user posted image
PM MAIL Jabber   Вверх
mastercz
Дата 12.11.2009, 09:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 112
Регистрация: 5.11.2008

Репутация: нет
Всего: нет



Решил все таки попробовать самостоятельно разбирать строчку при условии что это ОДНОМЕРНЫЙ ХЭШ,
однако столкнулся с некоторыми трудностями, так как обладаю весма скромными познаниями в регехп.
Подскажите пожалуйста, что тут не так:
Код

$JSON='{"sname":"Иван\","fname":"Иванов","pname":"Иванович"}'; #--> добавляю добавляю '\' для ошибки

#упрощенный вариант в идеале  (?<!\\) должен быть заменен на условие 
#при котором перед второй '"' должно быть или два символа '\'  или ни одного.
# но как-то не могу додуматься как это правильно описать.
my %HASH=$JSON=~/[\{|,]\"(.*?)(?<!\\)\":\"(.*?)(?<!\\)\"\}{0,1}/g;
print "\n-->".Dumper(\%HASH)."\n";



В результате получаю:

Код


-->$VAR1 = {
          'sname' => 'Иван\\",',
          'pname' => 'Иванович',
        };


Пока, отправлял сам увидел почему... 
Уточню вопрос  ... какое регулярное выражение нужно поставить вместо (?<!\\) чтобы перед закрывающейся кавычкой пропускать двойной слэш и не пропускать одинарный..



Это сообщение отредактировал(а) mastercz - 12.11.2009, 09:16
PM MAIL   Вверх
sir_nuf_nuf
Дата 12.11.2009, 13:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 920
Регистрация: 6.1.2008

Репутация: 14
Всего: 31



Код

(?<!\\\\)


Добавлено через 1 минуту и 28 секунд
первый слеш - это эскейп в самой регулярке.

P.S. а вообще - очень зря вы это затеяли.. поищите готовые парсеры.


JSON::XS - это супер круто. рекомендую использовать его. Но если вам по зарез нужно cp1251 - используйте JSON::PC - там есть опция отключения utf8


--------------------
user posted image
user posted image
PM MAIL Jabber   Вверх
mastercz
Дата 13.11.2009, 01:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 112
Регистрация: 5.11.2008

Репутация: нет
Всего: нет



по поводу слешей не точно выразился нужно чтобы работало условие или 2 слеша или не одного  (ибо 1 это экран).

sir_nuf_nuf, к сожалению JSON::PC вестимо приказал долго жить, так как оного не наблюдается на span.
Сейчас проверю как работает  модул Mojo::JSON

Проверил - тоже ставит флаг UTF8

Что же касается JSON::XS, охотно верю, так как другие JSON модули умирают ссылаясь в рекомендациях на оный. Однако,повторюсь, хранить в koi8-r  странице utf8 думаю не верно, ИМХО будут наблюдаться глюки.
Хранить же JSON в koi8-r, чтобы потом его конвертировать в UTF8 парсить и прогонять хэш через обратную конвертацию в koi8-r конечно можно, но как-то не очень вдохновляет. Делать Downgrade, тоже как-то, не очень вдохновляет (будет ли это поддерживаться в таком виде и дальше).
А к  JSON::XS думаю вернуться, как-только религия позволит перейти на уникод. 

Это сообщение отредактировал(а) mastercz - 13.11.2009, 01:49
PM MAIL   Вверх
mastercz
Дата 13.11.2009, 08:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 112
Регистрация: 5.11.2008

Репутация: нет
Всего: нет



Написал простенький парсер для строк вида {'КЛЮЧ1':'ЗНАЧЕНИЕ1','КЛЮЧ2':'ЗНАЧЕНИЕ2'}.
В первом приближении вроде бы как даже работает. Т. к. в я в этом не очень разбираюсь, может кто посмотрит и прокомментирует (укажет, подскажет) явные ошибки. Заранее благодарен за помощь.

А вот собственно и код:
Код

 package MyModul::Card;
 use strict;
 our $VERSION     = '0.01';
  
#-->> Создание класса-инструмента для работы с карточкой.
 sub new {
            my $invocant=shift();
            my $args=shift();
            my $class = ref($invocant) || $invocant;
            my $self ={};
               $self->{error}=undef;
             
            if( ref($args) eq 'HASH' and !$self->{error})
                {                 
                    $self->{error}=undef;
                    $args=undef;
                }
            elsif($args)
                {
                    $self->{error}='Error arguments for create class Card.';
                }
                                                
            bless $self => $class;
            
         return $self;
        }

#-->> МакроФункция decoder преобразует простой JSON обьект в Hash.
#     Аргументы: строка в формате простого JSON объекта.
#      Возвращает: Hash или Ноль.
sub decoder
    {
        my $self=shift();
        my $args=shift();
      
        my $MyCardStr            =undef;
        my $MyCardHash            ={};
        my $MyReturn            =0;        
        my $MyCL                ={    'char'=>undef, 
                                 'shield'=>0, 
                                 'blockname'=>undef, 
                                 'blockstat'=>'BEGIN', 
                                 'position'=>0, 
                                 'length'=>0
                             };
        my $MyRow                ={
                                 'key'=>'',
                                 'vaue'=>''
                              };                          

        
        if(ref($args) eq 'HASH' and !$self->{error})
               {
                 if(exists($args->{'MyCardStr'}))     {$MyCardStr=         $args->{'MyCardStr'};}
                 $args=undef;
               }
           else
               {
                   $self->{error}='Error arguments for decode function.';
               }

        if(ref($MyCardStr) ne '' and !$self->{error})
            {                
                 $self->{error}= "Bad status for 'MyCardStr' argument."; 
            }
                        
        if(!$self->{error})
            {
             $MyCL->{'length'}=length($MyCardStr);             
             if(!$MyCL->{'length'})    
                     {
                         $self->{error}= "Bad length for 'MyCardStr' argument.";
                     }            
            }

        if(!$self->{error})
            {
                while($MyCL->{'position'}<$MyCL->{'length'} and !$self->{error})
                    {
                        $MyCL->{'char'}=substr($MyCardStr,$MyCL->{'position'},1);
                                                
                                
                                if ($MyCL->{'blockstat'} eq 'BEGIN' )
                                        {
                                                if(substr($MyCardStr,$MyCL->{'position'},2) ne '{"') {$self->{error}='Bad begin block'; next;}
                                                    else {$MyCL->{'blockstat'}='KEY';$MyRow->{key}=''; $MyCL->{'position'}=$MyCL->{'position'}+1;}
                                        }
                                elsif($MyCL->{'blockstat'} eq 'KEY')
                                        {                                                
                                            if($MyCL->{'char'} eq "\"")
                                                {
                                                        if(!$MyCL->{'shield'}) {$MyCL->{'blockstat'}='COLON';}
                                                            else{$MyRow->{key}.=$MyCL->{'char'};$MyCL->{'shield'}=0;}    
                                                }
                                            elsif($MyCL->{'char'} eq "\\")
                                                {
                                                        if(!$MyCL->{'shield'}) {$MyCL->{'shield'}=1;}
                                                            else{$MyRow->{key}.=$MyCL->{'char'};$MyCL->{'shield'}=0;}                                        
                                                }
                                            else
                                                {
                                                        if(!$MyCL->{'shield'}) {$MyRow->{key}.=$MyCL->{'char'};}
                                                            else{$self->{error}='Bad begin shield whith key'; next;}                                        
                                                }                                                         
                                        }
                                elsif($MyCL->{'blockstat'} eq 'COLON')
                                        {
                                                if(substr($MyCardStr,$MyCL->{'position'},2) ne ':"') {$self->{error}='Bad format parameter'; next;}
                                                    else {$MyCL->{'blockstat'}='VALUE';$MyRow->{value}=''; $MyCL->{'position'}=$MyCL->{'position'}+1;}
                                        }
                                elsif($MyCL->{'blockstat'} eq 'VALUE')
                                        {
                                            if($MyCL->{'char'} eq "\"")
                                                {
                                                        if(!$MyCL->{'shield'}) {$MyCL->{'blockstat'}='SEPARATE';}
                                                            else{$MyRow->{value}.=$MyCL->{'char'};$MyCL->{'shield'}=0;}    
                                                }
                                            elsif($MyCL->{'char'} eq "\\")
                                                {
                                                        if(!$MyCL->{'shield'}) {$MyCL->{'shield'}=1;}
                                                            else{$MyRow->{value}.=$MyCL->{'char'};$MyCL->{'shield'}=0;}                                        
                                                }
                                            else
                                                {
                                                        if(!$MyCL->{'shield'}) {$MyRow->{value}.=$MyCL->{'char'};}
                                                            else{$self->{error}='Bad begin shield whith value'; next;}                                        
                                                }                                                         
                                        }
                                elsif($MyCL->{'blockstat'} eq 'SEPARATE')
                                        {
                                            if(substr($MyCardStr,$MyCL->{'position'},1) eq '}') 
                                                {
                                                    $MyCardHash->{$MyRow->{key}}=$MyRow->{value};
                                                    undef($MyRow);
                                                    $MyCL->{'blockstat'}='END';undef($MyRow);                                                        
                                                }
                                            elsif(substr($MyCardStr,$MyCL->{'position'},2) eq ',"')
                                                {
                                                    $MyCardHash->{$MyRow->{key}}=$MyRow->{value};
                                                    $MyCL->{'blockstat'}='KEY';$MyRow->{key}='';$MyRow->{value}='';$MyCL->{'position'}=$MyCL->{'position'}+1;                                                        
                                                }
                                            else
                                                {
                                                    $self->{error}='Bad format separate parameter'; next;
                                                }                                                    
                                            }
                                            
                                if($MyCL->{'position'}==$MyCL->{'length'}-1 )
                                            {
                                                if($MyRow->{key} or $MyRow->{value}) {$self->{error}='Bad input format'; next;}
                                            }

                        $MyCL->{'position'}=$MyCL->{'position'}+1;                                                                        
                    }                
            }
        
        if(!$self->{error} and scalar(keys(%{$MyCardHash})))
            {
                $MyReturn=$MyCardHash;
            }        
     return $MyReturn;
    }

sub DESTROY { my $self=shift();
        
           $self=undef;
        }
  
1;


PM MAIL   Вверх
Vaneska
Дата 19.11.2009, 19:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 141
Регистрация: 15.3.2005
Где: Москва

Репутация: 3
Всего: 4



JSON::XS->new->latin1->encode($hash);
JSON::XS->new->latin1->decode($text);

И ничего придумывать не нужно
--------------------
http://isokolov.blogspot.com/
PM MAIL ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Perl"
korob2001
sharq
  • В этом разделе обсуждаются общие вопросы по языку Perl
  • Если ваш вопрос относится к системному программированию, задавайте его здесь
  • Если ваш вопрос относится к CGI программированию, задавайте его здесь
  • Интерпретатор Perl можно скачать здесь ActiveState, O'REILLY, The source for Perl
  • Справочное руководство "Установка perl-модулей", можно скачать здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, korob2001, sharq.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Perl: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.3168 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.