2

While doing some HTML scrapping, I encounter this type of JS object:

[{
  key1: "Hello",
  key2: "There",
}, {
  key1: "Goodbye",
  key2: "See you",
},]

Note that keys aren't wrapped between " " so it isn't a valid JSON string. Therefore, I can't parse it to JSON/NSArray/NSDictionary without doing some processing.

Does any library/built-in-function exist that can convert this kind of string to an appropriate Objective-C object ?

ldiqual
  • 15,015
  • 6
  • 52
  • 90
  • Technically, if you can access a Javascript engine, you can [`eval`](http://jsfiddle.net/Y9kB7/). Maybe Objective-C has a comparable `eval` somewhere? (And that's not an endorsement of using `eval`, since, y'know, it's eViL and all.) – Jared Farrish Aug 05 '12 at 17:06
  • There is UIWebView's `stringByEvaluatingJavaScriptFromString:`, though I'm sure we all hope there's a better option... – Chris Trahey Aug 05 '12 at 17:09
  • Does the JSONKit's [`JKParseOptionStrict`](https://github.com/johnezang/JSONKit/#jkparseoptionflags) give the leeway to parse without the double-quoted labels? – Jared Farrish Aug 05 '12 at 18:21
  • Well, according to [JSONKit.h](https://github.com/johnezang/JSONKit/blob/master/JSONKit.h), `JKParseOptionStrict = JKParseOptionNone`... – ldiqual Aug 05 '12 at 18:45

1 Answers1

0

I finally found a solution on this Dimmzy's blog post (thanks to this almost identical question). Use this function to get a clean JSON string from a dirty one:

+ (NSString *)fixJSON:(NSString *)s {
  NSRegularExpression *regexp = [NSRegularExpression regularExpressionWithPattern:@"[{,]\\s*(\\w+)\\s*:"
                                                                          options:0
                                                                            error:NULL];
  NSMutableString *b = [NSMutableString stringWithCapacity:([s length] * 1.1)];
  __block NSUInteger offset = 0;
  [regexp enumerateMatchesInString:s
                           options:0
                             range:NSMakeRange(0, [s length])
                        usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) {
                          NSRange r = [result rangeAtIndex:1];
                          [b appendString:[s substringWithRange:NSMakeRange(offset, r.location - offset)]];
                          [b appendString:@"\""];
                          [b appendString:[s substringWithRange:r]];
                          [b appendString:@"\""];
                          offset = r.location + r.length;
                        }];
  [b appendString:[s substringWithRange:NSMakeRange(offset, [s length] - offset)]];
  return b;
}
Community
  • 1
  • 1
ldiqual
  • 15,015
  • 6
  • 52
  • 90