Replace Single Quotes With Double Quotes But Leave Ones Within Double Quotes Untouched
The ultimate goal or the origin of the problem is to have a field compatible with in json_extract_path_text Redshift. This is how it looks right now: {'error': 'Feed load failed: P
Solution 1:
Several ways, one is to use the regex
module with
"[^"]*"(*SKIP)(*FAIL)|'
In
Python
:
import regex as re
rx = re.compile(r'"[^"]*"(*SKIP)(*FAIL)|\'')
new_string = rx.sub('"', old_string)
With the original re
module, you'd need to use a function and see if the group has been matched or not - (*SKIP)(*FAIL)
lets you avoid exactly that.
Solution 2:
I tried a regex approach but found it to complicated and slow. So i wrote a simple "bracket-parser" which keeps track of the current quotation mode. It can not do multiple nesting you'd need a stack for that. For my usecase converting str(dict) to proper JSON it works:
example input:
{'cities': [{'name': "Upper Hell's Gate"}, {'name': "N'zeto"}]}
example output:
{"cities": [{"name": "Upper Hell's Gate"}, {"name": "N'zeto"}]}'
python unit test
deftestSingleToDoubleQuote(self):
jsonStr='''
{
"cities": [
{
"name": "Upper Hell's Gate"
},
{
"name": "N'zeto"
}
]
}
'''
listOfDicts=json.loads(jsonStr)
dictStr=str(listOfDicts)
if self.debug:
print(dictStr)
jsonStr2=JSONAble.singleQuoteToDoubleQuote(dictStr)
if self.debug:
print(jsonStr2)
self.assertEqual('''{"cities": [{"name": "Upper Hell's Gate"}, {"name": "N'zeto"}]}''',jsonStr2)
singleQuoteToDoubleQuote
defsingleQuoteToDoubleQuote(singleQuoted):
'''
convert a single quoted string to a double quoted one
Args:
singleQuoted(string): a single quoted string e.g. {'cities': [{'name': "Upper Hell's Gate"}]}
Returns:
string: the double quoted version of the string e.g.
see
- https://stackoverflow.com/questions/55600788/python-replace-single-quotes-with-double-quotes-but-leave-ones-within-double-q
'''
cList=list(singleQuoted)
inDouble=False;
inSingle=False;
for i,c inenumerate(cList):
#print ("%d:%s %r %r" %(i,c,inSingle,inDouble))if c=="'":
ifnot inDouble:
inSingle=not inSingle
cList[i]='"'elif c=='"':
inDouble=not inDouble
doubleQuoted="".join(cList)
return doubleQuoted
Post a Comment for "Replace Single Quotes With Double Quotes But Leave Ones Within Double Quotes Untouched"