Parse JSON but preserve \n in strings - javascript

I have this JSON string:
{\"text\":\"Line 1\\nLine 2\",\"color\":\"black\"}
I can parse it when I do this:
pg = JSON.parse(myJSONString.replace(/\\/g, ""));
But when I access pg.text the value is:
Line 1nLine 2.
But I want the value to be exactly:
Line 1\nLine 2
The JSON string is valid in terms of the target program which interprets it as part of a larger command. It's Minecraft actually. Minecraft will render this as you would expect with Line 1 and Line 2 on separate lines.
But I'm making a editor that needs to read the \n back in as is. Which will be displayed in an html input field.
Just as some context here is the full command which contains some JSON code.
/summon zombie ~ ~1 ~ {HandItems:[{id:"minecraft:written_book",Count:1b,tag:{title‌​:"",author:"",pages:‌​["{\"text\":\"Line 1\\nLine 2\",\"color\":\"black\"}"]}},{}]}

Try adding [1] at /\[1]/g but works for single slash only, but since the type of the quoted json i think is a string when you parse that it slash will automatically be removed so you don't even need to use replace. and \n will remain as.
var myString ='{\"text\":\"Line 1\\nLine 2\",\"color\":\"black\"}';
console.log(JSON.parse(myString.replace(/\\[1]/g, ""))); //adding [1] will remove single slash \\n -> \n
var myString =JSON.parse(myString.replace(/\\[1]/g, ""));
console.log(myString.text);

Your string is not valid JSON, and ideally you should fix the code that generates it, or contact the provider of it.
If the issue is that there is always one backslash too many, then you could do this:
// Need to escape the backslashes in this string literal to get the actual input:
var myJSONString = '{\\"text\\":\\"Line 1\\\\nLine 2\\",\\"color\\":\\"black\\"}';
console.log(myJSONString);
// Only replace backslashes that are not preceded by another:
var fixedJSON = myJSONString.replace(/([^\\])\\/g, "$1");
console.log(fixedJSON);
var pg = JSON.parse(fixedJSON);
console.log(pg);

Related

Javascript: read alert message from file and display with line break

How can I in Javascript read strings from a textfile and display them in an alert box with newlines?
Suppose I have an ASCII textfile "messages.txt" containing two lines:
AAA\nBBB\nCCC
DDD\nEEE\nFFF
In javascript, I read the file content and store it in a variable "m":
var m;
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function ()
{ if ((xmlhttp.readyState==4) && (xmlhttp.status==200 || xmlhttp.status==0))
{ m = xmlhttp.responseText.split('\n'); };
};
xmlhttp.open("GET", "messages.txt", false);
xmlhttp.send(null);
Now when I display the first message with
console.log(m[0]);
alert(m[0]);
it is shown exactly as in the textfile and with no line breaks; i.e
AAA\nBBB\nCCC
and not as
AAA
BBB
CCC
Changing \n to \\n, \r\n, \\r\\n or %0D%0A in the textfile doesn't help; the alert is still displayed as one line including the escape characters without replacing them by newline. Changing the encoding of "messages.txt" from ASCII to UTF-8 didn't help either.
To clarify the problem:
When m is read from the file "message.txt", it is split into an array of strings. m[0] equal to "AAA\nBBB\nCCC".
console.log(m[0]); // displays AAA\nBBB\nCCC
console.log('AAA\nBBB\nCCC'); // displays AAA
// BBB
// CCC
console.log(typeof(m[0]) // displays string
console.log(m[0]=="AAA\nBBB\nCCC"); // displays false
Why is m[0] not equal to "AAA\nBBB\nCCC" (even if exactly this is what is displayed in the console)? I guess, that is the reason why no line breaks appear.
you need to add another \ at split('\n') to be split('\\n')
or change the single quote to douple quotes split("\n")
also i encourage you to read this quick article about 'Single' vs "Double" quotes
Single quotes don't interpret newline breaks (\n). So, you need to change the quotes in your split() method to have double quotes.
Use the split() function like so.
const str = "Hi! I'm text!\nIsn't this supposed to be newline?";
console.log(str.split("\n"));
This should return an array like so when run.
[
"Hi! I'm text!",
"Isn't this supposed to be newline?"
]
This is how to separate your text with line breaks.
For more information, see this other Stack Overflow question.

Regular Express for Javascript - Contain a specific word in the beginning after get any character until a certain character comes

I need a certain type of regular expression where I need list of special type of strings from a string. Example input:
str = 'this is extra data which i do not need /type/123456/weqweqweqweqw/ these are more extra data which i dont need /'
Result needed:
/type/123456/weqweqweqweqw/
Here the /type/ string will be constant and the remaining will be dynamic i.e. 123456/weqweqweqweqw and the last string will be /.
I tried:
var myRe = /\/type\/(.*)\//g
But this matches everything from /type/ to the end of the string.
Instead of repeating ., which will match anything, repeat anything but a space via \S+, so that only the URL part of the string will be matched:
const str = 'this is extra data which i do not need /type/123456/weqweqweqweqw/ these are more extra data which i dont need /';
console.log(str.match(/\/type\S+/));
It's tagged Python, so here is a solution:
import re
re.search(r"/type/[^/]*/[^/]*/",str)
Out: <_sre.SRE_Match object; span=(39, 66), match='/type/123456/weqweqweqweqw/'>

Replace new line characters with \r

I'm using hl7parser to parse ADM files.
The documentation states that to create a new Message object, a string should be passed:
var message = hl7parser.create("MSH|^~\&|||||20121031232617||ADT^A04|20381|P|2.3||||NE\rEVN|A04|20121031162617||01\rPID|1|16194|16194||Jones^Bob");
Notice that the string uses '\r' to separate segments (MSH, EVN, PID).
I'm fetching the data from a server, which returns for instance the following data.
MSH|^~\&|EPICADT|DH|LABADT|DH|201301011226||ADT^A01|HL7MSG00001|P|2.3.1|
EVN|A01|201301011223||
PID|||MRN12345^5^M11||APPLESEED^JOHN^A^III||19710101|M||C|1 CATALYZE STREET^^MADISON^WI^53005-1020|GL|(414)379-1212|(414)271-3434||S||MRN12345001^2^M10|123456789|987654^NC|
NK1|1|APPLESEED^BARBARA^J|WIFE||||||NK^NEXT OF KIN
PV1|1|I|2000^2012^01||||004777^GOOD^SIDNEY^J.|||SUR||||ADM|A0|
Replacing the \n with \r with replace() doesn't make the parsing work, neither does split('\n') and join('\r').
I noticed that there is a difference when logging the string passed in the example and the string after replacing with \r
With string in example:
PID|1|16194|16194||Jones^BobADT^A04|20381|P|2.3||||NE
It's only printing the last segment apparently because of the \r characters
With my replacement method:
PID|||MRN12345^5^M11||APPLESEED^JOHN^A^III||19710101|M||C|1 CATALYZE STREET^^MADISON^WI^53005-1020|GL|(414)379-1PV1|1|I|2000^2012^01||||004777^GOOD^SIDNEY^J.|||SUR||||ADM|A0|
The entire string is printed, not just the last segment.
I'm not sure why there is a difference when printing them. Is there a difference between passing a literal string with \r character and "adding" \r to a string?
Doing this should work:
const lines = "A\nB\nC";
const result = lines.split("\n").join("\r");
console.log(result);
The confusion probably comes from the fact that it looks like it didn't, since it looks like it just output ABC.
However, if we check out the length of the string produced:
const lines = "A\nB\nC";
const result = lines.split("\n").join("\r");
console.log(result);
console.log(result.length);
Notice that it is 5 characters long, not 3. The \r is there. It's just that when it is output to most things, it basically gets hidden because an \r doesn't really render to anything on its own.
It is a "carriage return" and only MacOS (before X) used it as a newline character. Windows uses a combination of \r\n to render a newline and Linux (and MacOSX) uses \n.
If it wanted an explicitly shown in the string \r, then you'd need to use an escaped one (though this is almost certainly not what it expects):
const lines = "A\nB\nC";
const result = lines.split("\n").join("\\r");
console.log(result);
console.log(result.length);
function replaceLfWithCr(text) {
return text.replace(/\n/g, '\r');
}

Regex find string and replace that line and following lines

I am trying to find a regex to achieve the following criteria which I need to use in javascript.
Input file
some string is here and above this line
:62M:C111111EUR1211498,00
:20:0000/11111000000
:25:1111111111
:28C:00001/00002
:60M:C170926EUR1211498,06
:61:1710050926C167,XXNCHKXXXXX 11111//111111/111111
Output has to be
some string is here and above this line
:61:1710050926C167,XXNCHKXXXXX 11111//111111/111111
Briefly, find :62M: and then replace (and delete) the lines starting with :62M: followed by lines starting with :20:, :25:, :28c: and :60M:.
Or, find :62M: and replace (and delete) until the line starting with :61:.
Each line has fixed length of 80 characters followed by newline (CR LF).
Is this really possible with regex?
I know how to find a string and replace the same line where the string is. But here multiple lines to be removed which is quite hard for me.
Please could someone help me out if it is possible with regex.
Here it is. First I'm finding text to delete using regex (note that I'm using [^]* to match all the lines insted of .*, as it also matches newlines). Then I'm replacing it with a newline.
var regex = /:62M:.*([^]*):61:.*/;
var text = `some string is here and above this line
:62M:C111111EUR1211498,00
:20:0000/11111000000
:25:1111111111
:28C:00001/00002
:60M:C170926EUR1211498,06
:61:1710050926C167,XXNCHKXXXXX 11111//111111/111111`;
var textToDelete = regex.exec(text)[1];
var result = text.replace(textToDelete, '\n');
console.log(result);

string replace using a regex

I have a string after Json.stringify in javascript using node. I wanted to replace the text in the string which starts with 'ab' then followed by some numbers(atleast one digit), with 'ab^^^^^^' where the number of '^' s should be equal to the number of digits after ab. The text starting with ab can occur atleast once, In this example it occurs twice. I need help in regex and replacing the string
string - in this, text starting with ab occurs twice.
var str = JSON.stringify({"abc":{"idcardno":"ertyuiop","form":{"somestring":"This string:\n- can have multiple \nab12345ab5677\n","flag":"true","flag2":"false"},"anothertext":"samplestring","numbetstr":"7"}});
after the regex replace it should be like this
{"abc":{"idcardno":"ertyuiop","form":{"somestring":"This string:\n- can have multiple \na^^^^^ab^^^^\n","flag":"true","flag2":"false"},"anothertext":"samplestring","numbetstr":"7"}}
Edit
As per the post below the below will be the contents of obj.abc.form.string, coming in multiple lines. How do I do the regex(above mentioned) replace of this object?
This string:
- can have multiple
ab12345ab56778
Don't process stringifed JSON with regexp. Process the JavaScript object itself, then stringify. In your case, assuming obj is the input:
obj.abc.form.somestring = transform(obj.abc.form.somestring);
str = JSON.stringify(obj);
where transform is a regexp/replace making the transformation you want.
#torazaburo is right, it's a bad practice to manipulate JSON directly. Once you get ahold of the string in obj.abc.form.somestring, though, you can use replace, passing a function:
str.replace(/ab\d+/g, function(match) {return match.replace(/\d/g,'^')})

Categories

Resources