I have a string which is 'almost' a json string, only that its keys are not surrounded by quotes.
Normally it is used by the UI and javascript which does not have a problem in interpreting it. However it seems the JSON parsers in Java that i know of require key to be surrounded by quotes.
Is there a way i can convert the string to a valid json string, probably by using a regular expression in Java.
Or is there a JSON lib which is a bit lenient.
The String will be of the form
{
A : "Val1",
B : [ SOME NESTED STUFF],
C : "Val3"
}
and i need to convert it to
{
"A" : "Val1",
"B" : [ SOME NESTED STUFF],
"C" : "Val3"
}
without affecting any of the nested stuff. The number of keys ie A, B, C is fixed.
Thanks
P.S. I cannot get the appropriate JSON string returned to me, it is a pre existing code and it is quite risky to change it.
If you happen to use Jackson it has support for non-standard JSON including unquoted keys: http://www.cowtowncoder.com/blog/archives/2009/08/entry_310.html
If you are sure that all line starting with unquoted_word : need the word to be quoted, you could use something like:
str.replaceAll("(?m)^(\s+)(\w+)(\s*:)", "$1\"$2\"$3");
But if you can you are probably better off using a proper parser like other answers suggest.
If you really want a regex, this might work:
jsonString.replaceAll("(\\w+)\\s*\\:","\"$1\" :");
That said, if you are really worried about touching the nested stuff and corner cases, you want a real parser, not a regex. There's no way that a regex will be precise enough to avoid messing up if one of your values is the string " A : ". If pingw33n is correct about the jackson parser, it is by far the best answer.
use the following line code to enclose all the keys (single caps letter is considered a valid key here) with double quotes:
str = str.replaceAll("\s([A-Z])\s\:\s\"", "\"$1\" : ");
Related
I am working on an app that has a huge .json database, a lot of the strings I need in the .json file have curly brackets ("{", "}") inside them, which I do not want, like this:
[
{
"name": "Whatever",
"entries": [
"If something something {28} + {41.6} something"
]
}
]
And I need to get the string as "If something something 28 + 41.6 something".
I remove them by fetching the string I need and using this method:
public String formatText(String text) {
String newtext = text.replaceAll("\\{", "").replaceAll("\\}", "");
return newtext;
}
That works but makes everything really slow.
I had other characters in the file, like "#", that I had no problem removing in a text editor by selecting all of them and replacing by the empty string. But if I use the same logic with the curly brackets it will also remove the json object brackets.
Anyone can think of a way to edit this file and remove only the brackets inside the strings?
(I've thought of making a method that copies the strings, formats them and send them to a new .json, but that would be really innefective timewise, because there is a lot of different values inside every object.)
If you wanna use the find/replace functionality of text editors - using IDE like intelij - there is an option to replace stuff by regex.
E.g. this (?=\S.)({|}) should cover your case with braces in string only, while not touching json syntax braces. If you have other unique cases - they should be included in regex. Example - https://regex101.com/r/wbIgKX/1
Though, I would propose to create a proper json parser class specifically to deal with your stuff.
If you are sure that the JSON file is formatted like your example, you can check whether the line contains anything else then whitespaces and { or }
If the line contains anything else, then replace the brackets
If not, then don't replace
Try this:
convert the json array into JObject and then you can grab each individual element. then parse through that and replace the curly brackets.
String example = jObject.SelectToken("entries");
"entries": [
"If something something {28} + {41.6} something"
]
hope this helps :)
I have tried multiple way to resolve this issue but directly you cannot replace it. There is way to do it , First iterate the json and check whether the line contains curly brace or not. If contains then you can use str.replaceAll("[{}]", " ");. This will remove the all the curly braces and gives you the string without braces.
The best way to achieve is:
final String finalString = listId.getList().stream().map(String::valueOf).collect(Collectors.joining(",")).toString();
listId is a JsonArray.
Sample data:
{"630":{"TotalLength":"33-3/8" - 36-3/4""},"631":{"Length":"34 37 7/8"}}
We are facing the double quotes issue in JSON response. How we can replace the double quotes with " \" " which comes inside the key or value? Java is the development platform.
This answer is assuming that you are not in control of creating this JSON-like string. If you can control that part, then you should be escaping properly there itself.
In this case, since parsing systematically is not an option as it's not a valid JSON yet, all I could suggest is to go through the various strings and see if you can find a pattern on which you can apply some logic and escape all the "s which prevent the string from being a valid JSON.
Here is probably a way to start:
All of the "s that are needed to be there for the string to be a vaild JSON are surrounded by one or multiple characters among {, :, ,, and }, with or without space in between the " and the other JSON characters.
So, if you parse the JSON-like string using Java and look for all the "s, and, when encountered with one, if they are along with any of the above characters (with or without space in between), you just leave it as it is. If not, replace that " with a \".
Note that the above method may or may not work depending on the data in question. What I mean to convey is the approach that you may find useful if there's absolutely no way for the string to be escaped during it's creation, and, if these strings follow a strict pattern with respect to the unescaped "s.
I try design a simple all purpose Data Structure that must be convertable to JSON and back. Since I have names and types I need to find an expression for that.
So I look for something like name+type or name<type> or name:type (which i like) or name|type or type[name].
Are there any problems with that? I mean the : is already taken so I need to enclose the name and type (which is always a good idea).
Anything I need to know?
The colon : is part of the JSON syntax so you must enclose a name that contains a colon (as any name) in double quotes ". This
{
"foo:bar": "BAR",
"foo:baz": "BAZ"
}
is valid JSON. Check it at http://jsonlint.com/
The very simple JSON syntax can be read on the JSON.org site.
So, in a nutshell I'm trying to create a regex that I can use in a java program that is about to submit a JSON object to my php server.
myString.replaceAll(myRegexString,"");
My question is that I am absolutely no good with regex and to add onto that I need to escape the characters properly as its stored in a string, and then also escape the characters properly inside the regex. good lordy.
What I came up with was this:
String myRegexString = "[\"',{}[]:;]"
The first backslash was to escape outer quotes to get a " in there. And then it struck me that {} and [] are also regex commands. Would I escape those as well? Like:
String myRegexString = "[\"',\{\}\[\]:;]"
Thanks in advance. In case it wasnt clear from examples above the only characters I really care about at this moment in time is:
" { } [ ] , and also ; : ' for general sqlinj protection.
UPDATE:
This is the final regex:
[\\Q\"',{}[\]:;\\E] for anyone else curious. Thanks Amit!
Why don't you use an actual JSON encoding API/framework? What you're doing is not sanitizing. What you're doing is corrupting the data. If my name is O'Reilly, I want it to be spelled O'Reilly, not OReilly. If I send a message containing [ or {, I want these to be in the messages. Use a framework or API that escapes those characters when needed rather than removing them blindly.
Googling for JSON Java will lead you to many APIs and frameworks.
Try something like
String myRegexString = "[\\Q\"',{}[]:;\\E]";
now the characters between \Q and \E are now treated as normal characters.
I am trying to use a regular expression to have this kind of string
{
"key1"
:
value1
,
"key2"
:
"value2"
,
"arrayKey"
:
[
{
"keyA"
:
valueA
,
"keyB"
:
"valueB"
,
"keyC"
:
[
0
,
1
,
2
]
}
]
}
from
JSONObject.toString()
that is one long line of text in my Android Java app
{"key1":"value1","key2":"value2","arrayKey":[{"keyA":"valueA","keyB":"valueB","keyC":[0,1,2]}]}
I found this regular expression for finding all commas.
/(,)(?=(?:[^"]|"[^"]*")*$)/
Now I need to know:
0- if this is reliable, that is, does what they say.
1- if this is works also with commas inside double-quotes.
2- if this takes into account escaped double-quotes.
3- if I have to take into account also single quotes, as this file is produced by my app but occasionally it could be manually edited by the user.
5- It has to be used with the multi-line flag to work with multi-line text.
6- It has to work with replaceAll().
The resulting regular expression will be be used for replacing each symbol with a two-char sequence made of the symbol itself plus \n character.
The resulting text has to be still JSON text.
Subsequent replace actions will take place also for the other symbols
: [ ] { }
and other symbols that can be found in JSON files outside the alphanumeric sequences between quotes (I do not know if the mentioned symbols are the only ones).
Its not that much simple, but yes if you want to do then you need to filter characters([,{,",',:) and replace then with a new line character against it.
like:
[ should get replaced with [\n
Answer to your question is Yes its very much reliable and good to implement its just a single line of code doing all. Thats what regex is made for.
0- if this is reliable, that is, does what they say.
Let's break down the expression a little:
(,) is a capturing group that matches a single comma
(?=...) would mean a positive lookahead meaning the comma would need to be followed by a match of that group's content
(?:...)* would be a non-capturing group that can occur 0 to many times
[^"]|"[^"]*" would match either any character except a double quote ([^"]) or (|) a pair of double quotes with any character in between except other double quotes ("[^"]*")
As you can see especially the last part could make it unreliable if there are escaped double quotes in a text value, so the answer would be "this is reliable if the input is simple enough".
1- if this is works also with commas inside double-quotes.
If the double quote pairs are correctly identified any commas in between would be ignored.
2- if this takes into account escaped double-quotes.
Here's one of the major problems: escaped double quotes would need to be handled. This can get quite complex if you want to handle arbitrary cases, especially if the texts could contain commas as well.
3- if I have to take into account also single quotes, as this file is produced by my app but occasionally it could be manually edited by the user.
Single quotes aren't allowed by the JSON sepcification but many parsers support them because humans tend to use them anyway. Thus you might need to take them into account and that makes no. 2 even more complex because now there might be an unescaped double quote in a single quote text.
5- It has to be used with the multi-line flag to work with multi-line text.
I'm not entirely sure about that but adding the multi-line flag shouldn't hurt. You could add it to the expression itself though, i.e. by prepeding (?m).
6- It has to work with replaceAll().
In its current form the regex would work with String#replaceAll() because it only matches the comma - the lookahead is used to determine a match but won't result in the wrong parts being replaced. The matches themselves might not be correct though, as described above.
That being said, you should note that JSON is not a regular language and only regular languages are a perfect fit for regular expressions.
Thus I'd recommend using a proper JSON parser (there are quite a lot out there) to parse the JSON into POJOs (might just be a bunch of generic JsonObject and JsonArray instances) and reformat that according to your needs.
Here's an example of how Jackson could be used to accomplish that: https://kodejava.org/how-to-pretty-print-json-string-using-jackson/
In fact, since you're already using JSONObject.toString() you probably don't need the parser itself but just a proper formatter (if you want/need to roll your own you could have a look at the org.json.JSONObject sources ).