正则表达式匹配中的Perl循环

ui7jx7zq  于 2022-11-15  发布在  Perl
关注(0)|答案(1)|浏览(222)

请看以下命令:

perl -0777ne 'print "$&\n\n" while /"(QueryString|Params)":\[(\{"Name":".*?", ?"Value":".*?"\},? ?)*\]/g;' myfile.json

它的json字符串iterate through each match像:

{
    "Some": "Random stuff",
    "QueryString": [
       { "Name": "IsOrdered",    "Value": "1"              },
       { "Name": "TimeStamp",    "Value": "11654116426247" }
    ],
    "Params": [
       { "Name": "ClassName",    "Value": "PRODUCT"        },
       { "Name": "ListID",       "Value": "Products"       },
       { "Name": "Mode ",        "Value": "1"              },
       { "Name": "Dept"  ,       "Value": "5"              },
       { "Name": "HasPrevOrder", "Value": ""               }
    ],
    "And": {
        "QueryString":[]
    },
    "More": "like",
    "More+": "this"
}

现在,我的问题是如何遍历名称/值对的每个正则表达式匹配,并将它们连接回正常的http查询字符串?
例如,For

"QueryString":[{"Name":"IsOrdered", "Value":"1"}, {"Name":"TimeStamp", "Value":"11654116426247"}]

连接的输出应该

"QueryString":"IsOrdered=1&TimeStamp=11654116363378"

"QueryString":[]"QueryString":""的值
请注意,我希望执行正则表达式匹配和替换,因为我需要保留其余的JSON组件。我所讨论的JSON文件实际上是一个har文件。它的结构非常复杂,但
"(QueryString|Params)":\[(\{"Name":".*?", ?"Value":".*?"\},? ?)*\]
我只想换掉它,仅此而已

wn9m85ua

wn9m85ua1#

我会使用jq

jq '
   walk(
      if type == "object" then
         (
            ( .QueryString, .Params ) | select( . != null )
         ) |= (
            map( @uri "\( .Name )=\( .Value )" ) | join("&")
         )
      else
         .
      end
   )
'

jqplay上的Demo
这将修改所有包含其中一个键的元素的对象。我通常更喜欢更有针对性的东西(不仅仅是出于效率的原因,而是为了避免意外地更改一些不应该更改的东西),但我对HAR格式的知识还不足以做到这一点。
下面是一个同样可以完成该任务的Perl程序:

use feature qw( say );

use Cpanel::JSON::XS qw( decode_json encode_json );
use URI::Escape      qw( uri_escape_utf8 );

sub transform {
   for ( @_ ) {
      $_ =
         join "&",
            map {
               join "=",
                  map uri_escape_utf8( $_ ),
                     $_->@{qw( Name Value )}
            }
               @$_;
   }
}

sub fix {
   my $x = shift;
   my $type = ref( $x );
   if ( $type eq "HASH" ) {
      for my $k ( keys( %$x ) ) {
         for my $v ( $x->{ $k } ) {
            if ( $k eq "QueryString" || $k eq "Params" ) {
               transform( $v );
            } else {
               fix( $v );
            }
         }
      }
   }
   elsif ( $type eq "ARRAY" ) {
      fix( $_ ) for @$x;
   }
}

local $/;
while ( <> ) {
   my $data = decode_json( $_ );
   fix( $data );
   say( encode_json( $data ) );
}

相关问题