Split string by "\" Node.js - javascript

Hy everyone, I'm having some issues with split a string because when I log her value seems ok but in the final result appears "\" like,
"map":"{\"isRoot\": true, \"visible\": true}" instead of have "map":"{"isRoot": true, "visible": true}"
So I have this code
if(mapData!=undefined){
var map = mapData.map;
console.log("sendDeviceInfo getServicesMapInfoById map >>>>>>>>>>>>>>>>>>>>> ", map);
sendData.map=map;
createLog('debug', __dirname, __filename.slice(__dirname.length + 1, -3), device.id, 'sendDeviceInfo','sendData.map 1', sendData.map);
}
And my logs:
sendDeviceInfo getServicesMapInfoById map >>>>>>>>>>>>>>>>>>>>> {"isRoot": true, "visible": true}
4|wscontro | [2017-05-30 12:36:03.010] - debug: /opt/wscontroller/wscontroller-service/scripts/gps GpsController 58a8c61b-f11d-4874-91df-3a5205e4145f sendDeviceInfo sendData.map 1 "{\"isRoot\": true, \"visible\": true}"
Why is this happening?
--- solution
if(mapData!=undefined){
var map = mapData.map;
var aux = map.split('\\').join('');
var jsonObject = JSON.parse(aux);
sendData.map = jsonObject;
}

You can replace them like this
yourJsonString = yourJsonString.split('\\').join('');
var jsonObject = JSON.parse(yourJsonString);

That's nothing to worry about. That "\"s don't actually exist in the string.
When you use JSON.stringify in node.js, the result always has "\"s to escape special characters, and double quotes are special characters. That character is the unix escape character. That's why it appears kind of everywhere.

Try using below code to remove the escape sequence
mapData = mapData.replace(/\\"/g, '"');

Your Json string is using "-marks.
Since Json is a string itself, we need a solution to tell the compiler which "-marks are marking the string, and which "-marks are part of the string itself.
To do this it's very common among languages to use the -character, and by typing for instance \", you're 'escaping' the "-mark.
Imagine a string like this: He said to me: "Hi there". Now if we want to make this into a string we could try "He said to me: "Hi there".", though the compiler will see 2 strings and a lost period, because it does not distinguish between the start and end of the string, and the "-marks that are part of the content itself.
When you console.log() an actual string, it will not show the "-marks that show the start and end of the string, because it is not necessary. Because of that, there is no need to escape the "-marks in the string itself.
Whatever the createLog() function does, it apparently needs to note the string down as it being an actual string, and therefor it needs to escape the "-marks with a '\' sign.

Related

Best practice for converting string to object in JavaScript

I am working on a small UI for JSON editing which includes some object and string manipulation. I was able to make it work, but one of the fields is bit tricky and I would be grateful for an advice.
Initial string:
'localhost=3000,password=12345,ssl=True,isAdmin=False'
Should be converted to this:
{ app_server: 'localhost:3000', app_password:'12345', app_ssl: 'True', app_isAdmin: 'False' }
I was able to do that by first splitting the string with the ',' which returns an array. And then I would loop through the second array and split by '='. In the last step I would simply use forEach to loop through the array and create an object:
const obj = {}
arr2.forEach((item) => (obj[`app_${item[0]}`] = item[1]));
This approach works, but in case some of the fields, i.e password contains ',' or '=', my code will break. Any idea on how to approach this? Would some advanced regex be a good idea?
Edit: In order to make things simple, it seems that I have caused an opposite effect, so I apologize for that.
The mentioned string is a part of larger JSON file, it is the one of the values. On the high level, I am changing the shape of the object, every value that has the structure I described 'server='something, password=1234, ssl=True', has to be transformed into separate values which will populate the input fields. After that, user modify them or simply download the file (I have separate logic for joining the input fields into the initial shape again)
Observation/Limitation with the design that you have :
As per your comment, none of the special characters is escaped in any way then how we will read this string password=12345,ssl=True ? It will be app_password: 12345,ssl=True or app_password: 12345 ?
why localhost=3000 is converted into app_server: 'localhost:3000' instead of app_localhost: '3000' like other keys ? Is there any special requirement for this ?
You have to design your password field in the way that it will not accept at least , character which is basically used to split the string.
Here you go, If we can correct the above mentioned design observations :
const str = 'localhost=3000,password=123=45,ssl=True,isAdmin=False';
const splittedStr = str.split(',');
const result = {};
splittedStr.forEach(s => {
const [key, ...values] = s.split('=')
const value = values.join('=');
result[`app_${key}`] = value
});
console.log(result);
As you can see in above code snippet, I added password value as 123=45 and it is working properly as per the requirement.
You can use a regular expression that matches key and value in the key=value format, and will capture anything between single quotes when the value happens to start with a single quote:
(\w+)=(?:'((?:\\.|[^'])*)'|([^,]+))
This assumes that:
The key consists of alphanumerical characters and underscores only
There is no white space around the = (any space that follows it, is considered part of the value)
If the value starts with a single quote, it is considered a delimiter for the whole value, which will be terminated by another quote that must be followed by a comma, or must be the last character in the string.
If the value is not quoted, all characters up to the next comma or end of the string will be part of the value.
As you've explained that the first part does not follow the key=value pattern, but is just a value, we need to deal with this exception. I suggest prefixing the string with server=, so that now also that first part has the key=value pattern.
Furthermore, as this input is part of a value that occurs in JSON, it should be parsed as a JSON string (double quoted), in order to decode any escaped characters that might occur in it, like for instance \n (backslash followed by "n").
Since it was not clarified how quotes would be escaped when they occur in a quoted string, it remains undecided how for instance a password (or any text field) can include a quote. The above regex will require that if there is a character after a quote that is not a comma, the quote will be considered part of the value, as opposed to terminating the string. But this is just shifting the problem, as now it is impossible to encode the sequence ', in a quoted field. If ever this point is clarified, the regex can be adapted accordingly.
Implementation in JavaScript:
const regex = /(\w+)=(?:'(.*?)'(?![^,])|([^,]+))/g;
function parse(s) {
return Object.fromEntries(Array.from(JSON.parse('"server=' + s + '"').matchAll(regex),
([_, key, quoted, value]) => ["app_" + key, quoted ?? (isNaN(value) ? value : +value)]
));
}
// demo:
// Password includes here a single quote and a JSON encoded newline character
const s = "localhost:3000, password='12'\\n345', ssl='True', isAdmin='False'";
console.log(parse(s));

Access escaped properties of an object in javascript

I have an object with a property like this:
var RouteMetaSet = {
'\/user-management\/users': {
path: '/user-management/users',
name: 'User Management',
iconClassList: ['fa', 'fa-user'],
}
};
I can easily get the value of the property like this:
console.log(RouteMetaSet['\/user-management\/users'])
However, if I assign the key to a variable and then push it inside the brackets, it's impossible.
var originialString = /user-management/users;
var escapedString = originialString.replace(/[-/<>*()?]/g, "\\$&"); // it should be "\/user-management\/users"
console.log(RouteMetaSet[escapedString]); // undefined
Am I wrong somewhere on this point?
First. This:
var originialString = /user-management/users;
… is just syntax errors.
String literals in JS must be quoted.
Next:
Escape characters have meaning in JavaScript source code.
When the string literal is parsed by the JavaScript engine it is turned into the string. During this process, the escape characters are consumed.
They aren't part of the data at all. If you insert slashes with regular expressions, then you are just inserting slashes (not escape sequences) into the string.
var RouteMetaSet = {
'\/user-management\/users': {
path: '/user-management/users',
name: 'User Management',
iconClassList: ['fa', 'fa-user'],
}
};
var originialString = "/user-management/users";
console.log(RouteMetaSet[originialString]);
Aside: the / character does not need to be escaped in a JS string literal unless it forms part of the sequence </script> inside an inline script.
Generated code often escapes all / characters as a simple and effective way to avoid that problem.
If the property name included characters that did need to be escaped (such as a \) then, by the time the string had been parsed, it would be too late to sensibly do anything about it.
var originalString = "Example\t";
Is that supposed to be a tab or is it supposed to be a \ followed by a t?
If you can't trust the code to be right in the first place, you have a problem.

Parse Username and Domain name in JavaScript

I have a String like CORP\tmothy (general format is CORP\<username>) and I want to extract the word tmothy from this String
I am using split function , but its trying to split "\t" instead of "\". I have escaped the backslash using "\\", but still no luck.
This might be the case with any usernames starting with n , r , b etc as they are equivalent to \n,\b,\r
How do I overcome this with the JS script?
If you have a string 'CORP\tmothy', then doing .split('\') will definetely do the trick. Check this code:
var s = 'CORP\\tmothy'; // escaping backslash here prevents it to become TAB in the string variable
s.split('\\'); // returns ["CORP", "tmothy"]
You must be doing something wrong.

How to filter a string containing round brackets (or parenthesis) while using jsonpath?

js code is ....
var queryString = 'Dolphin Travels (Sagar Travels)';
var results = jsonPath(jsonvar, "$.availableTrips[?("+queryString+")]");
Error :
SyntaxError: jsonPath: unterminated string literal: _v.travels == 'Dolphin Travels (Sagar Travels)
First, let's get some prerequisites figured out:
You are searching 'Dolphin Travels (Sagar Travels)', but I don't see this in your test data (at least that you've shown), so I can't really tell what part of the object/array it is in (whether it is a value or a key).
Here is the sample data I'm working with:
var t = {
'availableTrips': [
{
'busType': 'Volvo A/C-Multi Axle Semi sleeper (2+2)',
'busTypeId': '101',
'fares': 250,
'travels': 'SVR Tours and Travel [Citizen]'
},
{
'busType': 'Lorem Ipsum',
'busTypeId': '102',
'fares': 300,
'travels': 'SVR Tours and Travel [Citizen]'
}
]
}
Simple usage of jsonPath (I'm also assuming you mean this jsonPath library, since you did not specify):
jsonPath(t,'$.availableTrips[?(/SVR/.test(#.travels))]');
Yields the array of objects in the availableTrips array since the string SVR (as a regex) is in both of them.
jsonPath(t,'$.availableTrips[?(/Volvo/.test(#.busType))]');
Yields only the first item in the availableTrips array, equivalent to t.availableTrips[0].
Now, to answer your question:
When escaping, you can use a backslash \, but since you are in a string that is interpreted, you'll need to escape it TWICE: \\. Once for the string being sent as a parameter for jsonParse and again as part of the expression being interpreted within jsonParse. Like so:
jsonPath(t,'$.availableTrips[?(/\\(2\\+2\\)/.test(#.busType))]');
Notice that I also had to escape the + quantifier, as well as the ( and ) group metacharacters.
In terms of sanitizing user input, e.g. var queryString = 'Dolphin Travels (Sagar Travels)';, you can perform the following (see What special characters must be escaped in regular expressions?):
var sanitizedQueryString = queryString.replace(/([\.\^\$\*\+\?\(\)\[\{\\\|])/g,'\\$1');

Matching string between first and last quote

I have a string that contains a JSON object. Problem is the object is being returned like this for some reason:
string (4345) "{ "blabla" : { "bleble" : "bloblo" } ...}"
I need to extract everything between the first and last quotation basicly so that I can then decode the object.
I tried this in javascript:
var myVar = myString.match(/\".+$\"/);
But it's not working. What's the appropriate RegEx for my problem?
So you know that (in your example) myString has your JSONed thing? Why not do:
var myVar = myString.substring(1, myString.length - 2);
If there's some other junk before or after your JSONed thing, I guess you could use the indexOf and lastIndexOf operations.
Also check out this question:
Regex to validate JSON
In response to the question in the comment:
//So let's say we have this string
example = '"[ { "title": "event1", "start": "NOW", } ]"'
//So our example string has quote literals around the bits we want
//indexOf gives us the index of the " itself, so we should add one
//to get the character immediately after the "
first_nonquote_character = example.indexOf('"') + 1
//lastIndexOf is fine as is, since substring doesn't include the character
//at the ending index
last_nonquote_character = example.lastIndexOf('"')
//So we can use the substring method of the string object and the
//indices we created to get what we want
string_we_want = example.substring(first_nonquote_character, last_nonquote_character)
//The value in string_we_want is
//[ { "title": "event1", "start": "NOW", } ]
Hope that helps. BTW if your JSON is actually coming back with the ', } ]"' at the end of it and that's not a typo, you'd probably want to do a string.replace(/, } ]"$/, '}]').
You just need to get the group submatch:
/"(.*)"/.exec(myString)[1]
This regex worked for me (I tested it with Rubular):
/"(.+)"/
And you could use it like this:
var newString = oldString.replace(/"(.+)"/, "$1");
Where the parens are for capturing what's in between the quotation marks (because you didn't want them, right?).
Try this:
var newstr = oldstr.match(/"(.+)"/)[1];

Categories