With re.sub:
re.sub(r'(:\s+"[^"]*)"(?=[^"]*",)', r'\1', json_str)
re.sub(r'(:\s+"[^"]*)"(?=[^"]*",)', r'\1\"', json_str)
(:\s+"[^"]*) matches the portion from last : to second " and put in captured group 1
" matches literal ", and the zero width positive lookahead (?=[^"]*",) makes sure the match is followed by another ", immediately prior to ,
In the first replacement, only the captured group is kept; and in the second the captured group is followed by escaped " in the replacement
Example:
In [163]: json_str = '{"name": "John"s Garage", "company": "ABC"}'
In [164]: re.sub(r'(:\s+"[^"]*)"(?=[^"]*",)', r'\1', json_str)
Out[164]: '{"name": "Johns Garage", "company": "ABC"}'
In [165]: re.sub(r'(:\s+"[^"]*)"(?=[^"]*",)', r'\1\"', json_str)
Out[165]: '{"name": "John\\"s Garage", "company": "ABC"}'