I think you should make / have some assumptions about "json" that are always true. If, for example, json objects always have a fixed attribute order, this can help a lot, especially if individual attributes are problematic.
I would try to match
{"DisplayName":"(.*?)","Time":(null|"[^"]*"),"OverallRank":(\d+),"AgeRank":(\d+)}
and then replace it with some βfixedβ function, which probably just uses capture groups and transcodes some kind of created ad-hoc object back into actual json. One option would be to expand (.*?) Only if something is wrong.
However, the whole approach is complicated with additional attributes and, moreover, with a flexible order of attributes (all of which can still be managed).
As you probably noticed, this only works if the assumption is on top. Depending on the assumptions you can make, the decision can be very simple. However, all this becomes cumbersome if these distorted elements are completely irregular. So ... lucky, I guess. Please post assumptions about what you think is true if you need more help. If not, the program should guess what it really meant. I mean, someone can mean:
{ "DisplayName":"I want to have a quotationmark followed by Time, all quoted and separated by a comma \",\"Time\":null, because that how I roll and this entry shall not have a Time attribute...", "OverallRank":2, "AgeRank":2 }
if the quotes are not escaped correctly, you will have a problem. But, as I said, you have to make some assumptions about json. I mean, the usual assumption about json is that it is valid, because otherwise it is just not json.