JSON parse valid rows of invalid string - javascript

I need to parse a json string with JSON.parse() but somethimes the input is not in the full format. for examle:
{
"x" : "x",
"x1" : "x1",
"x2" : "x2,
"x3" :
And the parsing is breaking obviously. But in this case I want to "save" the valid rows.
Is it possible?

Here is what you can do:
String.prototype.safeParser = function(){
try{
var that=this;
return JSON.parse(this);
}
catch(err){
if(this.length<3){
return {};
}
else if(this.charAt(this.length - 1) == "}"){
that = this.substring(0, this.length - 2) + "}";
}
else{
that = this.substring(0, this.length - 1) + "}";
}
return that.safeParser();
}
}
and use it like console.log(json_string.safeParser());
It checks whether the string is valid json, if it is not, it looks if it ends with curly braces, it removes one character at a time until it is valid json.
Note: this specific code only works for objects with curly braces, not arrays with square brackets. However, this might not be too hard to implement.
JS Fiddle Demo (open your console)

Related

Encoding string is differing with asp.net server.URL encoding when using '?' in the string

When I am using in aps.net to encode the string, the function I'm using is Server.UrlEncode(GAE?), which returns the string GAE%3f.
When I am using javascript function to encode encodeURIComponent(GAE?) it is returning GAE%3F.
But when i validate the string it will never match since my validation failing.
Requirement is there any way to encoded encodeURIComponent(GAE?) as GAE%3f as it is my requirement.
Other wise please let me know Server.UrlEncode code encoding it as capital 'F' this letter making difference.
Note:Any way to get 'F' in small case when I use encodeURIComponent(GAE?), The question mark (?) encoded as %3F but it should be %3f
I think the best approach would be to decode then do the comparison.
But if you have to do the comparison before that for any reason, this is the code you can use to change the encoded "special characters" to lower/upper:
string FixEncode(string val) {
var result = new StringBuilder(val);
int searchIndex = val.IndexOf('%');
while (searchIndex >= 0)
{
result[searchIndex + 1] = char.ToUpper(result[searchIndex + 1]);
result[searchIndex + 2] = char.ToUpper(result[searchIndex + 2]);
searchIndex = val.IndexOf('%', searchIndex + 2);
}
return result.ToString();
}
You can run this function on both strings and then compare:
if (FixEncode(str1) == FixEncode(str2)) { /*...*/ }
Please try Uri.EscapeDataString("?")

Building JavaScript Array in C#, apostrophes changing

I have done this to build JavaScript Arrays from int, double and string lists.
public string listToJsArray<T>(List<T> cslist)
{
bool numeric = true;
if(
!(typeof(T)==typeof(int)
|| typeof(T) == typeof(string)
|| typeof(T) == typeof(double))
)
{
throw (new ArgumentException(message: "Only int, double and string are supported"));
}
if(typeof(T)==typeof(string))
{
numeric = false;
}
string JsArray = "[";
for(int i=0;i<cslist.Count;i++)
{
string dataWithSurrendings = cslist[i].ToString();
if(!numeric)
{
dataWithSurrendings = "'" + cslist[i].ToString() + "'";
}
if(i !=0)
{
dataWithSurrendings = "," + dataWithSurrendings;
}
if(i +1==cslist.Count)
{
dataWithSurrendings = dataWithSurrendings + "]";
}
JsArray += dataWithSurrendings;
}
return JsArray;
}
My problem is when a list of strings is passed, apostrophes turn into '.
for example, a list of {"1","2","3","4","5","6","7"} becomes this:
['1','2','3','4','1','6','7']
What modification is needed in this function, to return a correct array in JavaScript?
None of solutions did solve the problem. With JsonConvert I get almost same result. The problem is the single or double quote in View editor have not the same encoding as CS string.
I'm assuming that you are doing this to drop into a webpage somewhere, something like:
<script>
#{
var output = listToJsArray(Model.SomeList);
}
var myArray = #Html.Raw(output);
// some Javascript using that array
</script>
Don't waste your time trying to do it yourself. It's a pain and you are reinventing the wheel. JSON is valid Javascript and a serialization of an array into JSON is absolutely identical to a Javascript array literal. So use Javascript. JSON.Net is really useful here:
<script>
#{
var output = Newtonsoft.Json.JsonConvert.SerializeObject(Model.SomeList);
}
var myArray = #Html.Raw(output);
// some Javascript using that array
</script>
The serializer will handle all the annoying escaping, special characters and edge cases for you.

Parsing javascript array with multiple keys

Hi I need to parse a JavaScript array that has multiple keys in it. Here is an example of what I need to do. Any help is appreciated.
[
week1{
Meth:100,
Marijuana:122,
pDrugs:12,
},
week2{
Meth:15,
Marijuana:30,
pDrugs:22,
},
]
I need this to be broken into separate arrays based on if it is week1 or week2. Thanks again in advance.
The end needs to be like this.
week1 = ["Meth:100,Marijuana:122,pDrugs12"] etc.
Your JSON has severe improper formatting. If it's already an object (which I'm guessing it isn't -- otherwise, you'd be getting unexpected token errors in your browser console), then change the brackets to braces, remove the trailing commas, and add colons after the object items that don't have them (after week1 and week2).
If what you have is a string (obtained from XHR or similar), you'll have to do all the changes mentioned above, as well as enclosing each object item within quotation marks. It should look like:
{
"week1": {
"Meth":100,
"Marijuana":122,
"pDrugs":12
},
"week2": {
"Meth":15,
"Marijuana":30,
"pDrugs":22
}
}
Whatever you're dealing with that's serving such horribly invalid JSON ought to be taken out back and shot. Be that as it may, this'll require some serious string manipulation. You're going to have to do some thorough massaging with String.replace() and some regular expressions.
After you get the JSON valid, then you can get week1 with JSON.parse and drilling down the resulting object.
function log(what) { document.getElementById('out').value += what + '\n------------------\n'; }
var tree = '[ week1{ Meth:100, Marijuana:122, pDrugs:12, }, week2{ Meth:15, Marijuana:30, pDrugs:22, }, ]';
// string is raw
log(tree);
tree = tree.replace(
'/\r?\n/g', '' // remove line breaks to make further regexps easier
).replace(
'[','{' // replace [ with {
).replace(
']','}' // replace ] with }
).replace(
/\w+(?=[\{\:])/g, // add quotes to object items
function($1) { return '"'+$1+'"'; } // using a lambda function
).replace(
/"\{/g, '": {' // add colon after object items
).replace(
/,(?=\s*\})/g, '' // remove trailing commas
);
// string has been fixed
log(tree);
var obj = JSON.parse(tree);
log('obj.week1 = ' + JSON.stringify(obj.week1));
log('obj.week1.Meth = ' + obj.week1.Meth);
#out {
width: 100%;
height: 170px;
}
<textarea id="out"></textarea>

argument problem On function argument ($0,$1);+jquery,js?

Doubt On function($0,$1);
// $0,$1 two argument
My question is this two argument are Not defined But it hold some data on it ???
can any on help to Understand
how this two argument run;
function strip_tags(input, allowed) {
allowed = (((allowed || "") + "").toLowerCase().match(/<[a-z][a-z0-9]*>/g) || []).join('');
//console.log('----------->'+allowed.join('ss'));
var tags = /<\/?([a-z][a-z0-9]*)\b[^>]*>/gi,
commentsAndPhpTags = /<!--[\s\S]*?-->|<\?(?:php)?[\s\S]*?\?>/gi;
return input.replace(commentsAndPhpTags,'').replace(tags, function ($0, $1) { // need help to understand $0 , $1
//console.log('----------->'+$1);
return allowed.indexOf('<' + $1.toLowerCase() + '>') > -1 ? $0 : '';
});
}
That is a really bad way to sanitize markup. It's almost guaranteed to have some loopholes. A simpler way would just be to strip all markup:
var stripTags = function(str) {
return str.replace(/<[^>]+>/g, '');
};
As far as allowing specific elements goes, it would be better to write a tokenizer, iterate over the tokens, drop everything that's not allowed, and then output the markup from those tokens.
But if you don't care to write a tokenizer, this would be a better way of going about it, even though it's still kind of crude:
var allowed = { p: true, a: true };
var sanitize = function(str) {
return str.replace(/<\s*\/?\s*([^\s>]+)[^>]*>/g, function(tag, name) {
if (!allowed[name.toLowerCase()]) {
return '';
}
return tag;
});
};
But as the comment above mentions, if you're only sanitizing a user's markup on the client-side, it's a major problem. You need to be doing sanitization on the server-side.
return input.replace(commentsAndPhpTags, '').replace(tags, function (input, group1) {
//console.log('----------->'+group1);
return allowed.indexOf('<' + group1.toLowerCase() + '>') > -1 ? input : '';
});
You regex /<\/?([a-z][a-z0-9]*)\b[^>]*>/gi contains only a group match, which will be the content inside parentheses ([a-z][a-z0-9]*), replace() will pass to your function the original string and the group matches.
However, your regex should be like this /(<\/?[a-z][a-z0-9]*\b[^>]*>)/gi in order to be able to strip the tags.

Detect difference between & and %26 in location.hash

Analyzing the location.hash with this simple javascript code:
<script type="text/javascript">alert(location.hash);</script>
I have a difficult time separating out GET variables that contain a & (encoded as %26) and a & used to separate variables.
Example one:
code=php&age=15d
Example two:
code=php%20%26%20code&age=15d
As you can see, example 1 has no problems, but getting javascript to know that "code=php & code" in example two is beyond my abilities:
(Note: I'm not really using these variable names, and changing them to something else will only work so long as a search term does not match a search key, so I wouldn't consider that a valid solution.)
There is no difference between %26 and & in a fragment identifier (‘hash’). ‘&’ is only a reserved character with special meaning in a query (‘search’) segment of a URI. Escaping ‘&’ to ‘%26’ need be given no more application-level visibility than escaping ‘a’ to ‘%61’.
Since there is no standard encoding scheme for hiding structured data within a fragment identifier, you could make your own. For example, use ‘+XX’ hex-encoding to encode a character in a component:
hxxp://www.example.com/page#code=php+20+2B+20php&age=15d
function encodeHashComponent(x) {
return encodeURIComponent(x).split('%').join('+');
}
function decodeHashComponent(x) {
return decodeURIComponent(x.split('+').join('%'));
}
function getHashParameters() {
var parts= location.hash.substring(1).split('&');
var pars= {};
for (var i= parts.length; i-->0;) {
var kv= parts[i].split('=');
var k= kv[0];
var v= kv.slice(1).join('=');
pars[decodeHashComponent(k)]= decodeHashComponent(v);
}
return pars;
}
Testing on Firefox 3.1, it looks as if the browser converts hex codes to the appropriate characters when populating the location.hash variable, so there is no way JavaScript can know how the original was a single character or a hex code.
If you're trying to encode a character like & inside of your hash variables, I would suggest replacing it with another string.
You can also parse the string in weird ways, like (JS 1.6 here):
function pairs(xs) {
return xs.length > 1 ? [[xs[0], xs[1]]].concat(pairs(xs.slice(2))) : []
}
function union(xss) {
return xss.length == 0 ? [] : xss[0].concat(union(xss.slice(1)));
}
function splitOnLast(s, sub) {
return s.indexOf(sub) == -1 ? [s] :
[s.substr(0, s.lastIndexOf(sub)),
s.substr(s.lastIndexOf(sub) + sub.length)];
}
function objFromPairs(ps) {
var o = {};
for (var i = 0; i < ps.length; i++) {
o[ps[i][0]] = ps[i][1];
}
return o;
}
function parseHash(hash) {
return objFromPairs(
pairs(
union(
location.hash
.substr(1)
.split("=")
.map(
function (s) splitOnLast(s, '&')))))
}
>>> location.hash
"#code=php & code&age=15d"
>>> parseHash(location.hash)
{ "code": "php & code", "age": "15d" }
Just do the same as you do with the first example, but after you have split on the & then call unescape() to convert the %26 to & and the %20 to a space.
Edit:
Looks like I'm a bit out of date and you should be using decodeURIComponent() now, though I don't see any clear explanation on what it does differently to unescape(), apart from a suggestion that it doesn't handle Unicode properly.
This worked fine for me:
var hash = [];
if (location.hash) {
hash = location.href.split('#')[1].split('&');
}

Categories

Resources