Skip to content Skip to sidebar Skip to footer

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)|'

See a demo on regex101.com.


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"