I have an invalid json string that contains variables in a specific format.
A variable start with 'VV' then key (only alphanumeric, * and _ characters) then ends with 'VV'.
There are some places where these variables are defined in invalid json string, that can in inside value of any property or inside array.
I have to bring all variables inside the double quotes, if they are not already. So that the json string becomes a valid one.
One can assume that if all such variable is resolved, the json becomes a valid one.
My sandbox is https://regex101.com/r/uE9vB2/6
I have spent so much time but i could not found a way to get this issue resolved.
PS : I am not able to resolve the array entities.
Edit : Grouping is not required, as i am using separate grouping structure. I just want to replace those variable with "was-a-var" for both in objects and array.
for input :
{
"arr1": [
"key9",
VVvariable1VV,
"VVvariable2VV"
"key6",
"key7"
],
"obj1": {
"key1": "VVvaria*ble3VV",
"key3": VVvariable4VV,
"key7": "value7"
},
"obj2": {
"key1": {
"key1": "value-changed",
"key5": "VVvari_able5VV",
"key6": "value6",
"key7": VV*VV
},
"key2": [
"VVvariableVV",
VV*VV
]
},
"key8" : "value",
"key3": VVvariableVV,
"key5": "VVvariableVV"
}
Expected string :
{
"arr1": [
"key9",
"was-a-var",
"VVvariable2VV"
"key6",
"key7"
],
"obj1": {
"key1": "VVvaria*ble3VV",
"key3": "was-a-var",
"key7": "value7"
},
"obj2": {
"key1": {
"key1": "value-changed",
"key5": "VVvari_able5VV",
"key6": "value6",
"key7": "was-a-var"
},
"key2": [
"VVvariableVV",
"was-a-var"
]
},
"key8" : "value",
"key3": "was-a-var",
"key5": "VVvariableVV"
}
Edit : javascript regex only.
You can use the following to match:
(?<!")VV[\w*]*?VV(?!")
And replace with the following:
"was-a-var"
See RegEx DEMO
Edit: For javascript:
([^"])VV[\w*]*?VV(?!")
and replace with:
$1"was-a-var"
See DEMO
Related
I have some json data i get from an API that i need to transform using jq into another json format for later use with ansible as part of an inventory script.
What i have is something like:
{
"results": [
{
"name": "hostname1",
"key1": "somevalue1",
"key2": "somevalue2",
"key3": "somevalue3"
},
{
"name": "hostname2",
"key1": "somevalue12",
"key2": "somevalue22",
"key3": "somevalue32"
},
{
"name": "hostname3",
"key1": "somevalue13",
"key2": "somevalue23",
"key3": "somevalue33"
}
]
}
and i need to transform this to look like this:
{
"_meta": {
"hostvars": {
"hostname1": {
"name": "hostname1",
"key1": "somevalue1",
"key2": "somevalue2",
"key3": "somevalue3"
},
"hostname2": {
"name": "hostname2",
"key1": "somevalue12",
"key2": "somevalue22",
"key3": "somevalue32"
},
"hostname3": {
"name": "hostname3",
"key1": "somevalue13",
"key2": "somevalue23",
"key3": "somevalue33"
}
}
}
}
Things i have not been able to figure out.
If i use something like:
cat input.json | jq '{_meta: { hostvars: { (.results[].name): (.results[]) } }}'
Then _meta and hostvars is repeated for each object in the input and that is not at all what i want, i need a common "header" and then the data under there.
Ideally i would like to also exclude the "name" part in the output since it is already used and duplicated, but this is just a bonus.
Advice on how to do this? or is the filter in jq always run against one object at a time?
I experimented a bit with --slurp but didn't get anywhere
The crucial part is: Take an array of objects and transform it into one (outer) object where the attribute names of that outer object are given by some attribute value of the inner objects. That's the job description for INDEX(filter).
So:
{ _meta : { hostvars: ( .results | INDEX(.name) ) } }
Using .results[] twice will iterate over the same list twice, giving you the cartesian product of each host with each of the other objects ( 3 x 3 = 9 ). You need to reference it once!
You can do something like below. The key to the logic is forming an array of objects, firstly by making the key name as .name and the value as the whole sub-object inside.
Once you have the array, you can un-wrap into a comma-separated list of objects using add.
{ _meta : { hostvars: ( ( .results | map( { ( .name ) : . } ) | add ) ) } }
Demo - jqplay
Yet another approach using from_entries could be:
jq '.results | map({key: .name, value: .}) | {_meta: {hostvars: from_entries}}'
{
"_meta": {
"hostvars": {
"hostname1": {
"name": "hostname1",
"key1": "somevalue1",
"key2": "somevalue2",
"key3": "somevalue3"
},
"hostname2": {
"name": "hostname2",
"key1": "somevalue12",
"key2": "somevalue22",
"key3": "somevalue32"
},
"hostname3": {
"name": "hostname3",
"key1": "somevalue13",
"key2": "somevalue23",
"key3": "somevalue33"
}
}
}
}
Demo
You'll probably want to take advantage of jq pipes.
cat input.json | jq '{ _meta : { hostvars : (.results | map({key : .name, value : del(. | .name) }) | from_entries) }}'
Map these results as if they were entries to a new set of entries where the key is .name, also removing the .name from .value as you do so:
.results | map({key : .name, value : del(. | .name) })
Then, form an object from the entries:
... | from_entries
NOTE: See Inian's answer for why the array syntax used by the OP does not work.
I have this JSON:
[
{
"key1": "value1",
"key2": "value2",
"key3": "value3",
"key4": "value4,
"key5": {
"subkey1": "subvalue1",
"subkey2": "subvalue2",
"subkey3": "subvalue3"
}
}
]
i want to build a new JSON using JQ, and add more items, let me explain, i want to get this:
{
"NEWKEY1": "NEWVALUE2",
"NEWKEY2": [
{
"NEWKEY3": "UPSNEWVALUE3",
"NEWKEY4": {
"key1": "value1",
"key2": "value2",
"key3": "value3",
"key4": "value4,
"key5": {
"subkey1": "subvalue1",
"subkey2": "subvalue2",
"subkey3": "subvalue3"
}
}
}
]
}
How i can get that?
Thanks all
If data.json contains the new data, and template.json contains the template with NEWKEY1, etc, then the following invocation produces the desired output:
jq --argfile in data.json '.NEWKEY2[0].NEWKEY4 = $in[0]' template.json
Quibble
Yes, I know that the jq manual deprecates --argfile, so feel free to use one of the many alternatives, but all currently available versions of jq support it, which is more than can be said for the similar alternatives....
I have a Json object like so:
{
"key" : "false",
"key2" : "1.00",
"key3" : "value"
}
How can I convert this in Typescript to get
{
"key" : false,
"key2" : 1.00,
"key3" : "value"
}
I have tried using JSON.parse(JSON.stringify(json)), JSON.parse(json) and Object.assign(object, json) but none of those solutions seem to work.
The basic problem is that JSON.parse will not automatically convert strings that happen to represent valid values of primitives such as booleans and floats. It simply keeps them as strings. For a simple case, such as the one you have given, it's easy enough to manually convert the strings:
let src = { "key": "false", "key2": "1.00", "key3": "value" };
let dst = {
key: src.key !== "true",
key2: parseFloat(src.key2),
key3: src.key3
};
I want to post a json code to an API by Postman chrome app but as error that server gives to me one of values that is object, must be string e.g. lock at this json code:
{
"key1": "value",
"key2": {
"subkey1": {
"subsubkey1": "value",
"subsubkey2": "value"
},
"subkey2": "value",
},
"key3": "value"
}
As you see value of subkey1 is object, what I have to do in the code to its value be string?
I don't want use any function or anything else, I just want subkey1 value in this code be string!
I used this:
{
"key1": "value",
"key2": {
"subkey1": '{
"subsubkey1": "value",
"subsubkey2": "value"
}',
"subkey2": "value",
},
"key3": "value"
}
and this:
{
"key1": "value",
"key2": {
"subkey1": "{
"subsubkey1": "value",
"subsubkey2": "value"
}",
"subkey2": "value",
},
"key3": "value"
}
but API gave me invalid json error!
Your last attempt is close, but you need to escape the inner quote marks so that they don't terminate the outer string. A backslash (\) is normally used for this purpose:
"subkey1": "{
\"subsubkey1\": \"value\",
\"subsubkey2\": \"value\"
}"
I have .asmx web service and method. But I'm not sure returns json.
Does it return as a Json?
<string xmlns="http://tempuri.org/">
{ "Table": [ { "Key1": "x", "Key2": "x", "Key3": "Ads" } ], "Key4": [ { "Key41": "30", "Key42": "12", "Key43": "1" } ], "Key5": [ { "Key51": "10.4.2017 00:00:00" } ] }
</string>
So method result page writes that text at the top:
This XML file does not appear to have any style information associated with it. The document tree is shown below.
Can I get this data as json ?
May help this one
$cont_data = array( "Table"=>array( "Key1"=> "x",
"Key2"=> "x",
"Key3"=> "Ads"
),
"Key4"=>array(
"Key41"=> "30",
"Key42"=> "12",
"Key43"=> "1"
),
"Key5"=>array(
"Key51"=>"10.4.2017 00:00:00"
)
);
return json_encode($cont_data);
You can get the result as json, json_decode() do this.