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

Hello Monks

I am looking to take in a set of data as a string, comprised of units in the following example format:

[-1,-1,32,45]

stored under variable names of the type "$node".

I would then like to search through this string and replace these units with other units of the form:

[1,39,2,45]

stored under another variable name "$newnode".

Maintaining the square brackets is critical as this will eventually be used to produce a JSON output. I would ideally like to use the s// approach however any advice would be greatly appreciated.

Many thanks!

Replies are listed 'Best First'.
Re: Replacement of Bracketed Expressions for JSON output
by ELISHEVA (Prior) on Feb 28, 2011 at 09:09 UTC

    If you are regularly working with JSON, have you considered using JSON?

    I realize there are times when one just wants something quick and dirty and throwaway. However, if this is more than a one-off throw-away need, devoting time to developing a collection of regexes to work with a well established streaming format seems to me a bit foolish. The code one writes will not have anywhere near the degree of long term reusability and reliability that a proper parsing module will.

    For example, can you be sure that your arrays will always have only scalar elements? What about arrays nested in arrays? Arrays of hashes? That isn't even a question you need to worry about if you use a module that knows how to parse JSON in full.

Re: Replacement of Bracketed Expressions for JSON output
by ikegami (Patriarch) on Feb 28, 2011 at 07:20 UTC
    (my $newnode = $node) =~ s/.*/[1,39,2,45]/s;

    I personally would forgot using s///.

    my $newnode = '[1,39,2,45]';
      Wow, thanks for the fast reply!

      I was thinking about using using s// as I will be reading in multiple file lines by line, e.g:

      [-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,-1,-1],[-1,-1,0,28],[0,27,0,29],[0,28,0,30]

      and the details of the units for the replacements are contained in:

      $node,e.g.

      [-1,-1,0,28],

      which will be replaced by other details contained in $newnode, e.g.

      [1,30,2,34],

      which is being uniquely generated on the fly.

      I was wondering if there is a way to have an effect of say:

      $line =~ s/$node/$newnode

      After which $line is printed to an output file?

      Thanks again!

        Ardil:

        I think I'll have to go with ELESHEVA on this one. Sure you could do it with regexes, but the JSON module doesn't seem to difficult to work with:

        #!/usr/bin/perl use strict; use warnings; use JSON; while (my $line = <DATA>) { my $data = decode_json $line; if ($data->[0] == -1 and $data->[1] == -1 and $data->[2] == 32 and $data->[3] == 45 ) { $data = [ 1, 39, 2, 45 ]; } print encode_json($data), "\n"; } __DATA__ [-1,-1,32,45] [-1,-1,-1,-1] [-1,-1,0,28] [0,27,0,29] [0,28,0,30]

        On my machine, it produces (as expected):

        $ perl 890521.pl [1,39,2,45] [-1,-1,-1,-1] [-1,-1,0,28] [0,27,0,29] [0,28,0,30]

        Update: Fixed attribution.

        ...roboticus

        When your only tool is a hammer, all problems look like your thumb.