【问题标题】:Replace single quotes in double quotes in brackets用括号中的双引号替换单引号
【发布时间】:2016-10-31 06:35:26
【问题描述】:

我必须修改一个文件 json.我必须将单引号替换为双引号,但我不能使用以下命令sed -i -r "s/'/\"/g" file,因为文件中有更多单引号我不会更改。

以下代码为字符串示例:

"categories": [['Clothing, Shoes & Jewelry', 'Girls'], ['Clothing, Shoes & Jewelry', 'Novelty, Costumes & More', 'Costumes & Accessories', 'More Accessories', 'Kids & Baby']]

理想的结果应该是:

"categories": [["Clothing, Shoes & Jewelry", "Girls"], ["Clothing, Shoes & Jewelry", "Novelty, Costumes & More", "Costumes & Accessories", "More Accessories", "Kids & Baby"]]

示例文件:

{"categories": [['Movies & TV', 'Movies']], "title": "Understanding Seizures and Epilepsy DVD"},
{"title": "Who on Earth is Tom Baker?", "salesRank": {"Books": 3843450}, "categories": [['Books']]},
{"categories": [['Clothing, Shoes & Jewelry', 'Girls'], ['Clothing, Shoes & Jewelry', 'Novelty, Costumes & More', 'Costumes & Accessories', 'More Accessories', 'Kids & Baby']], "description": "description, "title": "Mog's Kittens", "salesRank": {"Books": 1760368}}},
{"description": "Three Dr. Suess' Puzzles", "brand": "Dr. Seuss", "categories": [['Toys & Games', 'Puzzles', 'Jigsaw Puzzles']]},

我使用了正则表达式,但问题是我不知道括号中有多少元素。所以我想用一种方法来替换括号中的所有单引号,这是一个完美的方法,但我找不到解决方案。

【问题讨论】:

  • 您的意思是您只能更改给定行中的引号?你能发布一个(小)完整的 json 文件吗?
  • {"categories": [['Movies & TV', 'Movies']], "title": "了解癫痫发作和癫痫 DVD"}, {"title": "地球上的人是谁Tom Baker?", "salesRank": {"Books": 3843450}, "categories": [['Books']]}, {"categories": [['Clothing, Shoes & Jewelry', 'Girls'], ['服装、鞋子和珠宝'、'新奇、服饰及更多'、'服饰和配饰'、'更多配饰'、'儿童和婴儿']],“描述”:“描述”,“标题”:“Mog's Kittens", "salesRank": {"Books": 1760368}}}, {"description": "Three Dr. Suess' Puzzles", "brand": "Dr. Seuss", "categories": [['Toys &游戏”、“拼图”、“拼图”]]}、
  • 抱歉,很难阅读...但是如果您看到“类别”字段,我会将单引号更改为双引号...但是该字段中有不同数量的字符串。
  • 我冒昧地用您的评论编辑了您的帖子。行格式丢失了,所以如果你愿意,你可以再次edit。我看到的唯一问题是在任何地方更改为单引号都会破坏"Three Dr. Suess' Puzzles",因为字符串中有一个引号。那是你的问题吗?因为它很大。
  • 感谢您的修改,我编辑了帖子。无论如何,问题不在于“描述”字段,而是“类别”......我只会更改该字段中的单引号......但是,正如我所说,我不能使用这个sed -i -r "s/'/\"/g" file,因为,这样,我也更改了其他单引号(例如“三个苏斯博士的谜题”),我不想要这个。

标签: json regex sed


【解决方案1】:
#!/usr/bin/perl -w
use strict;

# read each line from stdin
while (my $l=<>) {    
   chomp($l); # remove newline char

   # split: get contents of innermost square brackets
   my @a=split(/(\[[^][]*\])/,$l);

   foreach my $i (@a) {
      # replace quotes iff innermost square brackets
      if ($i=~/^\[/) { $i=~s/'/"/g; }
   }

   # join and print
   print join('',@a)."\n";
}

【讨论】:

    【解决方案2】:

    我找到了一种方法,使用 python。

    请注意,由于单引号,python json 无法识别您提供的 json 流(还有一些复制/粘贴问题,缺少引号,我已修复)。

    我的解决方案是完全使用 python 库,我怀疑你可以用sed 做同样的事情,这就是为什么我提供它,尽管你没有提到这项技术。

    • 我使用ast.literal_eval 读取数据,因为它是具有精确python 语法的字典列表。对于ast,单引号不是问题
    • 我使用json.dump 写入数据。它使用双引号写入数据。
    • 请注意,我将其写入“假”文件(即具有 I/O 写入方法以“欺骗”json 序列化程序的字符串)。

    这是一个可以工作的独立 sn-p:

    import io
    
    foo = """[{"categories": [['Movies & TV', 'Movies']], "title": "Understanding Seizures and Epilepsy DVD"},
    {"title": "Who on Earth is Tom Baker?", "salesRank": {"Books": 3843450}, "categories": [['Books']]},
    {"categories": [['Clothing, Shoes & Jewelry', 'Girls'], ['Clothing, Shoes & Jewelry', 'Novelty, Costumes & More', 'Costumes & Accessories', 'More Accessories', 'Kids & Baby']], "description": "description", "title": "Mog's Kittens", "salesRank": {"Books": 1760368}},
    {"description": "Three Dr. Suess' Puzzles",
    "brand": "Dr. Seuss", "categories": [['Toys & Games', 'Puzzles', 'Jigsaw Puzzles']]}
    ]"""
    
    fp = io.StringIO()
    
    json_data=ast.literal_eval(foo)
    json.dump(json_data,fp)
    print(fp.getvalue())
    

    结果:

    [{"categories": [["Movies & TV", "Movies"]], "title": "Understanding Seizures and Epilepsy DVD"}, {"salesRank": {"Books": 3843450}, "categories": [["Books"]], "title": "Who on Earth is Tom Baker?"}, {"description": "description", "salesRank": {"Books": 1760368}, "categories": [["Clothing, Shoes & Jewelry", "Girls"], ["Clothing, Shoes & Jewelry", "Novelty, Costumes & More", "Costumes & Accessories", "More Accessories", "Kids & Baby"]], "title": "Mog's Kittens"}, {"brand": "Dr. Seuss", "description": "Three Dr. Suess' Puzzles", "categories": [["Toys & Games", "Puzzles", "Jigsaw Puzzles"]]}]
    

    这是一个完整的脚本,带有 2 个参数(输入文件和输出文件)并执行转换。如果您对 python 不满意,可以在现有的 bash 脚本中使用此脚本(例如,将其保存在 fix_quotes.py 中):

    import ast,json,sys
    
    input_file = sys.argv[1]
    output_file = sys.argv[2]
    
    with open(input_file,"r") as fr:
        json_data=ast.literal_eval(fr.read())
    with open(output_file,"w") as fw:
        json.dump(json_data,fw)
    

    【讨论】:

    • 有趣!我使用 [sed] 因为我必须更改的文件非常大......但我找不到解决方案,所以我接受其他解决方案......如果我使用 json 文件而不是字符串,这是否有效?我的意思是,有一个函数可以加载文件以使用此解决方案?
    • 非常感谢,这是我一直在寻找的解决方案...最后一件事,如果我尝试使用非常大的文件来执行此操作,我最终可以执行吗?大声笑
    • 最后给出了独立的例子。如果文件超过机器内存(实际上远低于该限制),这将失败,因为数据是立即加载的。请注意,我在开头和结尾添加了方括号,以便能够将其作为字典列表进行处理。可以想象一次加载 1 行(去掉方括号)并一次写入 1 行(一次一个字典)。
    • 好的,谢谢,我会尽快用我的文件尝试您的解决方案...再次感谢!
    猜你喜欢
    • 2021-08-12
    • 1970-01-01
    • 1970-01-01
    • 2018-05-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-23
    • 2018-11-18
    相关资源
    最近更新 更多