代码之家  ›  专栏  ›  技术社区  ›  cbll

有效地从JSON文件中删除无效字符?

  •  0
  • cbll  · 技术社区  · 6 年前

    我正在通过命令行读取一个文件。

    由于该文件是从Oracle导出的JSON,因此它具有一定的结构。由于某些原因,此默认结构不是有效的JSON。例子:

    // This isn't valid JSON
    ,"items":
    [
    {"id":123,"language":"ja-JP","location":"Osaka"}
    ,{"id":33,"language":"ja-JP","location":"Tokyo"}
    ,{"id":22,"language":"ja-JP","location":"Kentok"}
    ]}
    

    我希望它只是一个对象数组,因此具有预期的输出:

    // This is valid json
    [
    {"id":123,"language":"ja-JP","location":"Osaka"}
    ,{"id":33,"language":"ja-JP","location":"Tokyo"}
    ,{"id":22,"language":"ja-JP","location":"Kentok"}
    ]
    

    因此,我需要删除第1行(全部)以及最后一行 } 从文件的最后一行。

    正在通过命令行从输入中分析文件:

    file, err := ioutil.ReadFile(os.Args[1])
    

    // in func main()
    removeInvalidJSON(file, os.Args[1])
    
    // later on .. 
    func removeInvalidJSON(file []byte, path string) {
    
        info, _ := os.Stat(path)
        mode := info.Mode()
    
        array := strings.Split(string(file), "\n")
        fmt.Println(array)
    
        //If we have the clunky items array which is invalid JSON, remove the first line
        if strings.Contains(array[0], "items") {
            fmt.Println("Removing items")
            array = append(array[:1], array[1+1:]...)
        }
    
        // Finds the last index of the array
        lastIndex := array[len(array)-1]
    
        // If we have the "}" in the last line, remove it as this is invalid JSON
        if strings.Contains(lastIndex, "}") {
            fmt.Println("Removing }")
            strings.Trim(lastIndex, "}")
        }
    
        // Nothing changed?
        fmt.Println(array)
    
        ioutil.WriteFile(path, []byte(strings.Join(array, "\n")), mode)
    }
    

    上面的函数确实写入了我能看到的文件-但据我所知,它不会改变数组,也不会将其写入文件。

    如何有效地远程控制文件的第一行以及最后一个假大括号 } 从档案里?

    我在另一个函数中解开JSON:是否有一种方法可以使用 "encoding/json" 图书馆?

    1 回复  |  直到 6 年前
        1
  •  1
  •   Adrian    6 年前

    此代码有几个重要问题,导致其行为不符合预期。我已经注意到这些评论如下:

    func removeInvalidJSON(file []byte, path string) {
    
        info, _ := os.Stat(path)
        mode := info.Mode()
    
        array := strings.Split(string(file), "\n")
        fmt.Println(array)
    
        //If we have the clunky items array which is invalid JSON, remove the first line
        if strings.Contains(array[0], "items") {
            fmt.Println("Removing items")
            // If you just want to remove the first item, this should be array = array[1:].
            // As written, this appends the rest of the array to the first item, i.e. nothing.
            array = append(array[:1], array[1+1:]...)
        }
    
        // Finds the last ~index~ *line* of the array
        lastIndex := array[len(array)-1]
    
        // If we have the "}" in the last line, remove it as this is invalid JSON
        if strings.Contains(lastIndex, "}") {
            fmt.Println("Removing }")
            // Strings are immutable. `strings.Trim` does nothing if you discard the return value
            strings.Trim(lastIndex, "}")
            // After the trim, if you want this to have any effect, you need to put it back in `array`.
        }
    
        // Nothing changed?
        fmt.Println(array)
    
        ioutil.WriteFile(path, []byte(strings.Join(array, "\n")), mode)
    }
    

    我觉得你想要的更像是:

    func removeInvalidJSON(file []byte, path string) {
        info, _ := os.Stat(path)
        mode := info.Mode()
    
        array := strings.Split(string(file), "\n")
        fmt.Println(array)
    
        //If we have the clunky items array which is invalid JSON, remove the first line
        if strings.Contains(array[0], "items") {
            fmt.Println("Removing items")
            array = array[1:]
        }
    
        // Finds the last line of the array
        lastLine := array[len(array)-1]
    
        array[len(array)-1] = strings.Trim(lastLine, "}")
    
        fmt.Println(array)
    
        ioutil.WriteFile(path, []byte(strings.Join(array, "\n")), mode)
    }