JSON.parse not creating a json object in javascript - javascript

I am getting below string from upstream. Have no control over it.
b"{'text': 'Airtel Tower (# BT Tower in Chasdmzoa, Delhi)', 'sentiment': '0.25'}"
I want to change the string to JSON. So the first thing I did was removing preceeding b'....' (upstream is a python program that produces utf-8 string as an output). So I am removing 'b' using substr..
str = msg.payload.substr(1);
Then I am trying to convert the string to JSON using JSON.stringify and JSON.parse.
console.log(typeof(str));
var t = JSON.stringify(str);
console.log(typeof(t));
var t = JSON.parse(t);
console.log("First: " + t);
var t = JSON.parse(t);
console.log("Second " + t);
x = t.text;
y = t["text"];
console.log(x + " ---- " + y);
Console Output:
string
string
First: "{'text': 'Airtel Tower(# KT Tower in Bang, Greater K
n), 'sentiment': '0.25'}"
Second {'text': 'Vodafone Tower (# LT Tower in Delhi, Greater K
), 'sentiment': '0.25'}
undefined ---- undefined
It fails to convert it to object even though JSON.stringify removed the extra quotes etc. and JSON.parse doesn't seem to work. What am I doing wrong?

const input = "b'\"{'text': 'Airtel Tower (# BT Tower in Chasdmzoa, Delhi)', 'sentiment': '0.25'}\"'";
const cleanString = str => str.split('"')[1].replace(/'/g, '"');
console.log(input);
// Result
console.log(JSON.parse(cleanString(input)));
Explanation
Split the string with the double quote " as a delimiter
Get the second item. This will give you {'text': 'Airtel Tower (# BT Tower in Chasdmzoa, Delhi)', 'sentiment': '0.25'}
Replace single quotes ' with double quotes ". This will give you {"text": "Airtel Tower (# BT Tower in Chasdmzoa, Delhi)", "sentiment": "0.25"}
Call JSON.parse on the previous string to have your object

There's an issue here: single-quoted string literals aren't valid JSON. JSON is based on JavaScript, but it's not the same thing. If you're writing an object literal inside JavaScript code, fine; if you actually need JSON, you need to use ".

Simplest answer (for non-anti-eval-zealots):
var string = msg.payload.substring(3,msg.payload.length-2);
var t = eval("(" + string + ")");
If you can't stand, or can't use (strict mode?), eval, then you need to convert the single quotes to double quotes for parsing, as JSON only accepts double quotes:
var string = msg.payload.substring(3,msg.payload.length-2);
var t = JSON.parse(string.replace(/'/g, "\""));

Related

How should a JSON string with quotes inside can be parsed with javascript

var str = '{"Language":"en","Type":"General","Text":""Mela" means "apple" in Italian"}';
Now JSON.parse(str) throws this error
Uncaught SyntaxError: Unexpected token M in JSON at position 43
Now replacing quotes escapes whole string and parsed JSON is not usable anymore
str = str.replace(/\\([\s\S])|(")/g,"\\$1$2");
"{\"Language\":\"en\",\"Type\":\"General\",\"Text\":\"\"Mela\" means \"apple\" in Italian\"}"
Other solutions like below do not seem to be working in this scenario
How to escape a JSON string containing newline characters using JavaScript?
You need to add a backslash before each double quote within your string as:
const str = '{"Language":"en","Type":"General","Text": "\\"Mela\\" means \\"apple\\" in Italian"}';
const obj = JSON.parse(str)
console.log(obj.Text)
In JSON you don't escape double quotes of the property name or the begging of the property value, just escape what's inside property value:
{\"Text\":\"\"Mela\" means ....
It should be like this:
{"Text":"\"Mela\" means ....
This can be done with multiple replacements:
var str = '{"Language":"en","Type":"General","Text":""Mela" means "apple" in Italian"}';
str = str.replace(/"/,"'"); //Replace all " with '
str = str.replace(/{'/,'{"') //Restore " to start of JSON
str = str.replace(/','/,'","'); //Restore " around JSON , separators
str = str.replace(/':'/,'":"'); //Restore " around JSON : separators
str = str.replace(/'}/,'"}'); //Restore " to end of JSON
str = str.replace(/'/,'\"'); //All remaining ' must be inside of data, so replace with properly escaped \"
console.log(str);
EDIT: A problem with this solution is that is will also replace original ' characters with " inside the text.

capture the string next to known string using javascript/jQuery

I have a long string. How can I find a string next to the known string.
example: '.lot of text..."number":"999.999.9999","make_model":"device name"....lot of text.'.
I know this value "999.999.9999". Using this as a sub string how do I capture "device name" and pass it as an alert/console.log? The device name is not a constant length.
Thanks
you can do something like this if you are sure the number is only repeated once and length is always the same and make_model is always next to it.
basically it finds index of number and adds the length of number plus make_model ("999.999.9999","make_model":") which is 29 characters. and then we get the rest of string after this until we reach a double quotation and thats the end of make_model and what you want.
var str = '.lot of text..."number":"999.999.9999","make_model":"device name"....lot of text.';
var chop = str.substr(str.indexOf('"999.999.9999"') + 29);
chop = chop.substring(0,chop.indexOf('"'));
console.log(chop);
A very straight forward answer is using JSON.parse()
/* surround string with braces { <your string> } */
var input_str = '{' + '"foo":"bar","number":"999.999.9999","make_model":"some model name","device name":"some dummy device","name":"Arvind","profile":"freelancer"' + '}';
var json = JSON.parse(input_str);
console.log(json['device name']);

RegExp select values

I've got the string variable, containing the folowing text:
var val1="GES3 02R202035 ";
var val2=0;
var val3="06 ";
var val4="03.01.11i";
var val5="";
I want to use RegExp to get the array of values and filter values from trailing spaces also.
/="?([\w\s\.]*)/g helps alot, except trailing spaces, and i'm not sure about other charachters there could be.
So I need something like /="?(.*);/g but it doesn't remove last " and spaces also.
/="?(.*)"?;/g doesn't remove last ", who know why?
Could please anybody help me with this?
Edit:
The expected output is:
GES3 02R202035
0
06
03.01.11i
and empty string here
Edit:
I need this in javascript (node.js) str.match(/?????/);
Edit: With the help of Wiktor Stribiżew and melpomene finally I came to:
(notice lookbehind in regex, it will work in chrome with harmony flag enabled only)
var str =
'var val1="GES3 02R202035 ";\n' +
'var val2=0;\n' +
'var val3="06 ";\n' +
'var val4="03.01.11i";\n' +
'var val5="";\n';
console.log('before:\n' + str);
var parts = str.match(/(?<=="?)[^"]*?(?=\s*"?;)/g);
console.log('parts\n', parts);
The problem with str.match() was that it return array of matches, and I actually need array of groups. The solution was to arrange RegEx to match exactly the result what I need. It became possible with the latest V8 and its support of lookbehind.
var str =
'var val1="GES3 02R202035 ";\n' +
'var val2=0;\n' +
'var val3="06 ";\n' +
'var val4="03.01.11i";\n' +
'var val5="";\n';
console.log('before:\n' + str);
var re = /=\s*(?:([-+]?\d+(?:\.\d+)?)|"([^"]*)")/g;
var parts = [];
var m;
while (m = re.exec(str)) {
var x =
m[1] !== undefined
? Number(m[1])
: m[2].trim()
parts.push(x);
}
console.log('parts\n', parts);
This code extracts the embedded numbers and strings (after a = sign). Numbers (in the format (- | +)? digits (. digits)?, i.e. an optional sign and optional decimal places are accepted) are converted to JS numbers; strings have their contents extracted and trimmed.
It does not support exponential notation (1e2) or backslash escapes in strings.

Parse string having key=value pairs as JSON

My node app receives a series of strings in the format "a=x b=y c=z" (i.e. a string containing several space-separated key=value pairs).
What is the neatest way of converting such a string into a JSON object of the form {a: x, b: y, c: z}?
I'm betting that there's a one-line solution, but haven't managed to find it yet.
Thanks.
One way would be to replace the with a , and an = with a ::
var jsonStr = '{' + str.replace(/ /g, ', ').replace(/=/g, ': ') + '}';
Or if you need quotes around the keys and values:
var jsonStr2 = '{"' + str.replace(/ /g, '", "').replace(/=/g, '": "') + '"}';
JSON.parse() it if you need.
Sample output:
str: a=x b=y c=z
jsonStr: {a: x, b: y, c: z}
jsonStr2: {"a": "x", "b": "y", "c": "z"}
Building on John Bupit's excellent answer, I have made a couple of further enhancements to end up with the following (the string being parsed being in message):
var json = JSON.parse(('{"' + message.replace(/^\s+|\s+$/g,'').replace(/=(?=\s|$)/g, '="" ').replace(/\s+(?=([^"]*"[^"]*")*[^"]*$)/g, '", "').replace(/=/g, '": "') + '"}').replace(/""/g, '"'));
Basically the scheme is as follows:
First replace(): trim off any leading or trailing whitespace -- equivalent to trim()
Second replace(): add double quotes (empty string) for any value that is completely missing (e.g. key1= key2=val goes to key1="" key2=val).
Third replace(): replace each space (which acts as a delimiter) with ", ", but not where the space is within double quotes (i.e. part of a string value).
Fourth replace(): replace each = with ": "
Wrap the entire string up as follows: {"..."}
Finally, replace any double quotes "" created by the above steps (because the value string was already wrapped in quotes in message) with single quotes "
Even more finally, run JSON.parse() over the result.
The above scheme should cope with missing values, with some values being quoted and some unquoted, and with spaces within value strings, e.g. something like a= b="x" c="y y" d=z.
Assuming that you don't get nested objects in that format :
var sample = 'a=x b=y c=z';
var newobj = {};
sample.split(' ').forEach(function (value) {
var keypair = value.split('=');
newobj[keypair[0]] = keypair[1];
});
console.dir(newobj);
What this does is split on every white-space and push to an array, and the array is looped and each item in array is split again to get each key-value pair which is assigned to the newobj.
Here's a simple function that will do the trick
function stringToObj (string) {
var obj = {};
var stringArray = string.split(' ');
for(var i = 0; i < stringArray.length; i++){
var kvp = stringArray[i].split('=');
if(kvp[1]){
obj[kvp[0]] = kvp[1]
}
}
return obj;
}
newstr = ""
for kvp in #value.split(" ")
newstr += kvp.replace(/=/,'":"').replace(/^/, '"').replace(/$/, '"').replace(/\"\"/,'" "')
newstr = newstr.replace(/\"\"/g, '","')
jsn = JSON.parse('{' + newstr + '}')
I created a simple online tool for similar need: https://superal.github.io/online-tools/
Use cases:
To transfer key:value pairs copied from chrome network requests(form data or query string parameters) or postman headers key-value(in bulk edit style) to json format.
For example:
key:value pairs
platform:2
limit:10
start_time:1521561600
end_time:1522080000
offset:0
to json format
{
"platform": "2",
"limit": "10",
"start_time": "1521561600",
"end_time": "1522080000",
"offset": "0"
}
It can be parsed (converted to json) using the help of this npm athena-struct-parser package.
For more information about the package -- https://www.npmjs.com/package/athena-struct-parser
Sample Nodejs Code
var parseStruct =require('athena-struct-parser') ;
var str = '{description=Check the Primary key count of TXN_EVENT table in Oracle, datastore_order=1, zone=yellow, aggregation_type=count, updatedcount=0, updatedat=[2021-06-09T02:03:20.243Z]}'
var parseObj = parseStruct(str)
console.log(parseObj);
Sample string with key=value format taken
{description=Check the Primary key count of TXN_EVENT table in Oracle, datastore_order=1, zone=yellow, aggregation_type=count, updatedcount=0, updatedat=[2021-06-09T02:03:20.243Z]}
Result Parsed output
{
description: 'Check the Primary key count of TXN_EVENT table in Oracle',
datastore_order: '1',
zone: 'yellow',
aggregation_type: 'count',
updatedcount: '0',
updatedat: [ '2021-06-09T02:03:20.004Z' ]
}
I would use an approach leveraging URLSearchParams and Object.fromEntries() like so:
const input = "a=x b=y c=z";
const queryString = input.replaceAll(" ", "&");
const query = new URLSearchParams(queryString);
const output = Object.fromEntries(query);
console.log(output);
Breakdown:
The URLSearchParams constructor takes a string of key-value pairs joined by "&" as it's argument, and parses it into a URLSearchParams object instance. So to use this, the space separators in the original input need to be replaced with a "&" character.
The URLSearchParams instance we have after parsing is an iterable, so we can transform it into a plain Object with Object.fromEntries().
It's not too bad as a one-liner either:
const input = "a=x b=y c=z";
const output = Object.fromEntries(new URLSearchParams(input.replaceAll(" ", "&")));

Convert string with commas to array

How can I convert a string to a JavaScript array?
Look at the code:
var string = "0,1";
var array = [string];
alert(array[0]);
In this case alert shows 0,1. If it where an array, it would show 0. And if alert(array[1]) is called, it should pop-up 1
Is there any chance to convert such string into a JavaScript array?
For simple array members like that, you can use JSON.parse.
var array = JSON.parse("[" + string + "]");
This gives you an Array of numbers.
[0, 1]
If you use .split(), you'll end up with an Array of strings.
["0", "1"]
Just be aware that JSON.parse will limit you to the supported data types. If you need values like undefined or functions, you'd need to use eval(), or a JavaScript parser.
If you want to use .split(), but you also want an Array of Numbers, you could use Array.prototype.map, though you'd need to shim it for IE8 and lower or just write a traditional loop.
var array = string.split(",").map(Number);
Split it on the , character;
var string = "0,1";
var array = string.split(",");
alert(array[0]);
This is easily achieved in ES6;
You can convert strings to Arrays with Array.from('string');
Array.from("01")
will console.log
['0', '1']
Which is exactly what you're looking for.
If the string is already in list format, you can use the JSON.parse:
var a = "['a', 'b', 'c']";
a = a.replace(/'/g, '"');
a = JSON.parse(a);
Convert all type of strings
var array = (new Function("return [" + str+ "];")());
var string = "0,1";
var objectstring = '{Name:"Tshirt", CatGroupName:"Clothes", Gender:"male-female"}, {Name:"Dress", CatGroupName:"Clothes", Gender:"female"}, {Name:"Belt", CatGroupName:"Leather", Gender:"child"}';
var stringArray = (new Function("return [" + string+ "];")());
var objectStringArray = (new Function("return [" + objectstring+ "];")());
JSFiddle https://jsfiddle.net/7ne9L4Lj/1/
Result in console
Some practice doesnt support object strings
- JSON.parse("[" + string + "]"); // throw error
- string.split(",")
// unexpected result
["{Name:"Tshirt"", " CatGroupName:"Clothes"", " Gender:"male-female"}", " {Name:"Dress"", " CatGroupName:"Clothes"", " Gender:"female"}", " {Name:"Belt"", " CatGroupName:"Leather"", " Gender:"child"}"]
For simple array members like that, you can use JSON.parse.
var listValues = "[{\"ComplianceTaskID\":75305,\"RequirementTypeID\":4,\"MissedRequirement\":\"Initial Photo Upload NRP\",\"TimeOverdueInMinutes\":null}]";
var array = JSON.parse("[" + listValues + "]");
This gives you an Array of numbers.
now you variable value is like array.length=1
Value output
array[0].ComplianceTaskID
array[0].RequirementTypeID
array[0].MissedRequirement
array[0].TimeOverdueInMinutes
You can use split
Reference:
http://www.w3schools.com/jsref/jsref_split.asp
"0,1".split(',')
Another option using the ES6 is using Spread syntax.
var convertedArray = [..."01234"];
var stringToConvert = "012";
var convertedArray = [...stringToConvert];
console.log(convertedArray);
use the built-in map function with an anonymous function, like so:
string.split(',').map(function(n) {return Number(n);});
[edit] here's how you would use it
var string = "0,1";
var array = string.split(',').map(function(n) {
return Number(n);
});
alert( array[0] );
How to Convert Comma Separated String into an Array in JavaScript?
var string = 'hello, world, test, test2, rummy, words';
var arr = string.split(', '); // split string on comma space
console.log( arr );
//Output
["hello", "world", "test", "test2", "rummy", "words"]
For More Examples of convert string to array in javascript using the below ways:
Split() – No Separator:
Split() – Empty String Separator:
Split() – Separator at Beginning/End:
Regular Expression Separator:
Capturing Parentheses:
Split() with Limit Argument
check out this link
==> https://www.tutsmake.com/javascript-convert-string-to-array-javascript/
You can use javascript Spread Syntax to convert string to an array. In the solution below, I remove the comma then convert the string to an array.
var string = "0,1"
var array = [...string.replace(',', '')]
console.log(array[0])
I remove the characters '[',']' and do an split with ','
let array = stringObject.replace('[','').replace(']','').split(",").map(String);
More "Try it Yourself" examples below.
Definition and Usage
The split() method is used to split a string into an array of substrings, and returns the new array.
Tip: If an empty string ("") is used as the separator, the string is split between each character.
Note: The split() method does not change the original string.
var res = str.split(",");
Regexp
As more powerful alternative to split, you can use match
"0,1".match(/\d+/g)
let a = "0,1".match(/\d+/g)
console.log(a);
Split (",") can convert Strings with commas into a String array, here is my code snippet.
var input ='Hybrid App, Phone-Gap, Apache Cordova, HTML5, JavaScript, BootStrap, JQuery, CSS3, Android Wear API'
var output = input.split(",");
console.log(output);
["Hybrid App", " Phone-Gap", " Apache Cordova", " HTML5", "
JavaScript", " BootStrap", " JQuery", " CSS3", " Android Wear API"]
var i = "[{a:1,b:2}]",
j = i.replace(/([a-zA-Z0-9]+?):/g, '"$1":').replace(/'/g,'"'),
k = JSON.parse(j);
console.log(k)
// => declaring regular expression
[a-zA-Z0-9] => match all a-z, A-Z, 0-9
(): => group all matched elements
$1 => replacement string refers to the first match group in the regex.
g => global flag
Why don't you do replace , comma and split('') the string like this which will result into ['0', '1'], furthermore, you could wrap the result into parseInt() to transform element into integer type.
it('convert string to array', function () {
expect('0,1'.replace(',', '').split('')).toEqual(['0','1'])
});
Example using Array.filter:
var str = 'a,b,hi,ma,n,yu';
var strArr = Array.prototype.filter.call(str, eachChar => eachChar !== ',');

Categories

Resources