tejD has asked for the wisdom of the Perl Monks concerning the following question:

Hi, I am using perl 5.22.0-r0. It has very basic package. I installed it using opkg. Problem: I am passing json from page for eg {'k1':'v1','k2':'v2'} which I am able to receive in my CGI script. But I am unable to parse it and store into a variable. I know, I need to use JSON module. But I can not install it due to limitation. Is there any alternative way to parse json without json module? Thanks.

Replies are listed 'Best First'.
Re: Can not use JSON module
by choroba (Cardinal) on Jun 02, 2017 at 13:33 UTC
    Your string isn't a valid JSON. I tried with the recommended JSON::PP:
    #!/usr/bin/perl use strict; use feature qw{ say }; use warnings; use JSON::PP; my $json = "{'k1':'v1','k2':'v2'}"; decode_json($json);

    Error:

    unexpected end of string while parsing JSON string, at character offse +t 2 (before "k1':'v1','k2':'v2'}")

    JSON::XS gives even more informative message:

    '"' expected, at character offset 1 (before "'k1':'v1','k2':'v2'}")

    JSON understands double quotes only:

    '{"k1":"v1","k2":"v2"}'
    ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,
Re: Can not use JSON module
by tobyink (Canon) on Jun 02, 2017 at 13:25 UTC

    Maybe try using JSON::PP instead. Almost identical interface, but it's installed by default with Perl since 5.13.9.

Re: Can not use JSON module
by 1nickt (Canon) on Jun 02, 2017 at 13:27 UTC
Re: Can not use JSON module
by stevieb (Canon) on Jun 02, 2017 at 13:45 UTC

    Following up on what tobyink and 1nickt said, in a recent distribution I wrote, I let the compiler decide whether to use JSON (XS) or JSON::PP which is already in the core. If JSON is not installed, it'll automatically fall back to the core JSON::PP.

    BEGIN { # look for JSON::XS, and if not available, fall # back to JSON::PP to avoid requiring non-core modules my $json_ok = eval { require JSON::XS; JSON::XS->import; 1; }; if (! $json_ok){ require JSON::PP; JSON::PP->import; } }
      Isn't that what JSON does? See also JSON::MaybeXS .

      ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,

        But that's the point. The OP says that they cannot install JSON "due to limitation" (whatever that may mean). This is therefore a nice means for them to choose between the modules which actually do the work without having to install the non-core JSON module.

        I thought so, but I'm sure when I tested it on a box without JSON::XS it failed. I could have been imagining things at the time after a long day of work, so I'll re-test this today.

Re: Can not use JSON module
by karlgoethebier (Abbot) on Jun 02, 2017 at 15:09 UTC
    "...alternative way to parse json without json module?"

    merlyn tried it some years ago at JSON parser as a single Perl Regex. But i guess your JSON needs to be valid however.

    Minor update: Fixed link.

    «The Crux of the Biscuit is the Apostrophe»

    Furthermore I consider that Donald Trump must be impeached as soon as possible

      Hi, Sorry for the given JSON(it was only for example). I also checked and tried to use JSON::PP which comes as default. But my current perl does not have this also. I have installed perl 5.22.0-r0 via OPKG. It shows very basic module. I am not doing this on our general linux(eg ubuntu). I am doing it on board which has linux OS. So, I used OPKG to install perl which is supported by linux on that board. So, I am searching for function or something that I can use in my CGI script to decode json. Thanks.

        You can install JSON::PP by copying the files onto your machine.

        Also, consider maybe JSON::Tiny, which can also be installed by copying.

        "...I am searching for function..."

        Yes, sure. I got it. Here it is (as i already mentioned):

        #!/usr/bin/env perl use strict; use warnings; use Data::Dumper qw(Dumper); my $FROM_JSON = qr{ (?&VALUE) (?{ $_ = $^R->[1] }) (?(DEFINE) (?<OBJECT> (?{ [$^R, {}] }) \{ (?: (?&KV) # [[$^R, {}], $k, $v] (?{ # warn Dumper { obj1 => $^R }; [$^R->[0][0], {$^R->[1] => $^R->[2]}] }) (?: , (?&KV) # [[$^R, {...}], $k, $v] (?{ # warn Dumper { obj2 => $^R }; [$^R->[0][0], {%{$^R->[0][1]}, $^R->[1] => $^R->[2]}] }) )* )? \} ) (?<KV> (?&STRING) # [$^R, "string"] : (?&VALUE) # [[$^R, "string"], $value] (?{ # warn Dumper { kv => $^R }; [$^R->[0][0], $^R->[0][1], $^R->[1]] }) ) (?<ARRAY> (?{ [$^R, []] }) \[ (?: (?&VALUE) (?{ [$^R->[0][0], [$^R->[1]]] }) (?: , (?&VALUE) (?{ # warn Dumper { atwo => $^R }; [$^R->[0][0], [@{$^R->[0][1]}, $^R->[1]]] }) )* )? \] ) (?<VALUE> \s* ( (?&STRING) | (?&NUMBER) | (?&OBJECT) | (?&ARRAY) | true (?{ [$^R, 1] }) | false (?{ [$^R, 0] }) | null (?{ [$^R, undef] }) ) \s* ) (?<STRING> ( " (?: [^\\"]+ | \\ ["\\/&#660;bfnrt] # | # \\ u [0-9a-fA-f]{4} )* " ) (?{ [$^R, eval $^N] }) ) (?<NUMBER> ( -? (?: 0 | [1-9]\d* ) (?: \. \d+ )? (?: [eE] [-+]? \d+ )? ) (?{ [$^R, eval $^N] }) ) ) }xms; sub from_json { local $_ = shift; local $^R; eval { m{\A$FROM_JSON\z}; } and return $_; die $@ if $@; return 'no match'; } my $json = q({"k1":"v1","k2":"v2"}); print Dumper from_json($json); __END__ karls-mac-mini:Desktop karl$ ./godfather.pl $VAR1 = { 'k2' => 'v2', 'k1' => 'v1' };

        Update: Oops!. Better with Data::Dumper

        Thank merlyn for the regex.

        Regards, Karl

        «The Crux of the Biscuit is the Apostrophe»

        Furthermore I consider that Donald Trump must be impeached as soon as possible

        If you are using opkg to install packages you are not using "it on a board which has linux OS".

        You seem to be using OpenWrt which is a different OS.

        It may help to indicate which version you are using and what device you use.