Matching and storing part of a string in a variabl

2019-08-10 07:04发布

问题:

I am fiddling with some a script for Fiddler, which uses JScript.NET. I have a string of the format:

{"params":{"key1":"somevalue","key2":"someothervalue","key3":"whatevervalue", ...

I want to match and show "key2":"someothervalue" where someothervalue could be any value but the key is static.

Using good old sed and bash I can replace the part I am looking for with:

$ a='{"params":{"key1":"somevalue","key2":"someothervalue","key3":"whatevervalue", ...'
$ echo $a | sed -r 's/"key2":"[^"]+"/replaced/g'
{"params":{"key1":"somevalue",replaced,"key3":"whatevervalue", ...

Now. Instead of replacing it, I want to extract that part into a variable using JScript.NET. How can that be done?

回答1:

The most graceful way is to use a JSON parser. My personal preference is to import IE's JSON parser using the htmlfile COM object.

import System;

var str:String = '{"params":{"key1":"foo","key2":"bar","key3":"baz"}}',
    htmlfile = new ActiveXObject('htmlfile');

// force htmlfile COM object into IE9 compatibility
htmlfile.IHTMLDocument2_write('<meta http-equiv="x-ua-compatible" content="IE=9" />');

// clone JSON object and methods into familiar syntax
var JSON = htmlfile.parentWindow.JSON,

// deserialize your JSON-formatted string
    obj = JSON.parse(str);

// access JSON values as members of a hierarchical object
Console.WriteLine("params.key2 = " + obj.params.key2);

// beautify the JSON
Console.WriteLine(JSON.stringify(obj, null, '\t'));

Compiling, linking, and running results in the following console output:

params.key2 = bar
{
        "params": {
                "key1": "foo",
                "key2": "bar",
                "key3": "baz"
        }
}

Alternatively, there are also at least a couple of .NET namespaces which provide methods to serialize objects into a JSON string, and to deserialize a JSON string into objects. Can't say I'm a fan, though. The ECMAScript notation of JSON.parse() and JSON.stringify() are certainly a lot easier and profoundly less alien than whatever neckbeard madness is going on at Microsoft.


And while I certainly don't recommend scraping JSON (or any other hierarchical markup if it can be helped) as complicated text, JScript.NET will handle a lot of familiar Javascript methods and objects, including regex objects and regex replacements on strings.

sed syntax:

echo $a | sed -r 's/("key2"):"[^"]*"/\1:"replaced"/g'

JScript.NET syntax:

print(a.replace(/("key2"):"[^"]*"/, '$1:"replaced"'));

JScript.NET, just like JScript and JavaScript, also allows for calling a lambda function for the replacement.

print(
    a.replace(
        /"(key2)":"([^"]*)"/,

        // $0 = full match; $1 = (key2); $2 = ([^"]*)
        function($0, $1, $2):String {
            var replace:String = $2.toUpperCase();
            return '"$1":"' + replace + '"';
        }
    )
);

... Or to extract the value of key2 using the RegExp object's exec() method:

var extracted:String = /"key2":"([^"]*)"/.exec(a)[1];
print(extracted);

Just be careful with that, though, as retrieving element [1] of the result of exec() will cause an index-out-of-range exception if there is no match. Might either want to if (/"key2":/.test(a)) or add a try...catch. Or better yet, just do what I said earlier and deserialize your JSON into an object.