转义JSON字符串中的特殊字符

时间:2019-07-06 18:49:29

标签: json perl escaping character

我有一个Perl脚本,其中包含变量$env->{'arguments'},该变量应包含一个JSON对象,我想将该JSON对象作为参数传递给我的其他外部脚本,并使用反引号来运行它。

$env->{'arguments'}在转义前的值:

$VAR1 = '{"text":"This is from module and backslash \\ should work too"}';

转义后的$env->{'arguments'}的值:

$VAR1 = '"{\\"text\\":\\"This is from module and backslash \\ should work too\\"}"';

代码:

print Dumper($env->{'arguments'});
escapeCharacters(\$env->{'arguments'});
print Dumper($env->{'arguments'});

my $command = './script.pl '.$env->{'arguments'}.'';
my $output = `$command`;

转义符功能:

sub escapeCharacters
{
    #$env->{'arguments'} =~ s/\\/\\\\"/g;
    $env->{'arguments'} =~ s/"/\\"/g;
    $env->{'arguments'} = '"'.$env->{'arguments'}.'"';
}

我想问你什么是正确的方法,以及如何将JSON字符串解析为有效的JSON字符串,我可以将其用作脚本的参数。

2 个答案:

答案 0 :(得分:2)

您正在重新发明wheel

use String::ShellQuote qw( shell_quote );

my $cmd = shell_quote('./script.pl', $env->{arguments});
my $output = `$cmd`;

或者,您可以使用许多IPC ::模块来代替qx。例如,

use IPC::System::Simple qw( capturex );

my $output = capturex('./script.pl', $env->{arguments});

因为至少有一个参数,所以也可以使用以下参数:

my $output = '';
open(my $pipe, '-|', './script.pl', $env->{arguments});
while (<$pipe>) {
   $output .= $_;
}

close($pipe);

请注意,当前目录不一定是包含执行脚本的目录。如果要执行与当前正在执行的脚本位于同一目录中的script.pl,则需要进行以下更改:

添加

use FindBin qw( $RealBin );

并替换

'./script.pl'

使用

"$RealBin/script.pl"

答案 1 :(得分:1)

将其传递到第二个程序而不是将其作为参数传递似乎更有意义(并且更加安全)。

test1.pl

#!/usr/bin/perl

use strict;
use JSON;
use Data::Dumper;

undef $/;

my $data = decode_json(<>);
print Dumper($data);

test2.pl

#!/usr/bin/perl

use strict;
use IPC::Open2;
use JSON;

my %data = ('text' => "this has a \\backslash", 'nums' => [0,1,2]);
my $json = JSON->new->encode(\%data);

my ($chld_out, $chld_in);
print("Executing script\n");
my $pid = open2($chld_out, $chld_in, "./test1.pl");
print $chld_in "$json\n";
close($chld_in);
my $out = do {local $/; <$chld_out>};
waitpid $pid, 0;
print(qq~test1.pl output =($out)~);