【问题标题】:Replace single quotes with double quotes but leave ones within double quotes untouched用双引号替换单引号,但保持双引号内的不受影响
【发布时间】:2019-08-31 05:13:47
【问题描述】:

最终目标或问题的根源是在 json_extract_path_text Redshift 中有一个兼容的字段。

这就是现在的样子:

{'error': "Feed load failed: Parameter 'url' must be a string, not object", 'errorCode': 3, 'event_origin': 'app', 'screen_id': '6118964227874465', 'screen_class': 'Promotion'}

为了从 Redshift 中的字符串中提取我需要的字段,我将单引号替换为双引号。 特定记录给出错误,因为在错误值内部,那里有一个单引号。这样,如果这些字符串也被替换,字符串将是无效的 json。

所以我需要的是:

{"error": "Feed load failed: Parameter 'url' must be a string, not object", "errorCode": 3, "event_origin": "app", "screen_id": "6118964227874465", "screen_class": "Promotion"}

【问题讨论】:

  • 你试过json.dumps(d)吗?

标签: python


【解决方案1】:

我尝试了一种正则表达式方法,但发现它既复杂又缓慢。所以我写了一个简单的“括号解析器”来跟踪当前的报价模式。它不能做多重嵌套,你需要一个堆栈。对于我将 str(dict) 转换为正确 JSON 的用例,它可以工作:

示例输入: {'cities': [{'name': "Upper Hell's Gate"}, {'name': "N'zeto"}]}

示例输出: {"cities": [{"name": "Upper Hell's Gate"}, {"name": "N'zeto"}]}'

python 单元测试

def testSingleToDoubleQuote(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

    def singleQuoteToDoubleQuote(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 in enumerate(cList):
                #print ("%d:%s %r %r" %(i,c,inSingle,inDouble))
                if c=="'":
                    if not inDouble:
                        inSingle=not inSingle
                        cList[i]='"'
                elif c=='"':
                    inDouble=not inDouble
            doubleQuoted="".join(cList)    
            return doubleQuoted

【讨论】:

  • 当在单引号中找到单引号时,这将是有问题的。即:"{'cities': [{'name': 'Upper Hell's Gate'}]" => '{"cities": [{"name": "Upper Hell"s Gate"}]'。单元测试中的 jsonStr 似乎也没有经过任何转换,除了双引号内没有单引号。正则表达式不应该太慢,如果您的用例不同,还有其他 pcre 引擎/语言。
  • 单引号中的单引号在我的用例中不会发生,这将是 python 和/或 JSON 的语法错误。
【解决方案2】:

有几种方法,一种是使用regex模块与

"[^"]*"(*SKIP)(*FAIL)|'

a demo on regex101.com


Python:
import regex as re

rx = re.compile(r'"[^"]*"(*SKIP)(*FAIL)|\'')
new_string = rx.sub('"', old_string)

使用原始的 re 模块,您需要使用一个函数来查看该组是否匹配 - (*SKIP)(*FAIL) 可以让您完全避免这种情况。

【讨论】:

    猜你喜欢
    • 2018-11-18
    • 2021-08-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-12
    • 1970-01-01
    • 1970-01-01
    • 2018-09-23
    相关资源
    最近更新 更多