如何在Golang中替换JSON字符串中的双引号?
解决Golang与BigQuery中含未转义双引号的JSON解析问题
问题本质
你的JSON字符串存在格式非法问题:字段值内的双引号未转义(比如"Wrong type of argument for function "NONE"...里的"NONE"),直接导致标准JSON解析器无法正常工作。正则表达式因无法处理JSON的嵌套结构和上下文语义,无法彻底解决该问题。
Golang解决方案
放弃正则处理JSON,改用状态机预处理转义值内的未转义双引号,确保JSON格式合法后再用标准库解析。示例代码如下:
package main import ( "bytes" "encoding/json" "fmt" ) func fixUnescapedQuotes(jsonStr []byte) []byte { var result bytes.Buffer inString := false inEscape := false for _, c := range jsonStr { switch { case c == '\\': inEscape = !inEscape result.WriteByte(c) case c == '"' && !inEscape: if inString { // 检查前一个非空白字符是否为冒号,判断是否是字段值的结束引号 lastNonSpace := byte(0) for i := result.Len() - 1; i >= 0; i-- { b := result.Bytes()[i] if b != ' ' && b != '\t' && b != '\n' && b != '\r' { lastNonSpace = b break } } if lastNonSpace != ':' { // 属于值内未转义引号,添加转义符 result.WriteByte('\\') } } inString = !inString result.WriteByte(c) default: inEscape = false result.WriteByte(c) } } return result.Bytes() } func main() { rawJSON := []byte(`{ "Responses": [], "SessionParameters(Updated)": { "counter-no-match-nombre": "($session.params.counter-no-match, 1)", "message": "Hello." }, "SystemFunctionResults": { "SystemFunctionErrors": [ { "Message": "Wrong type of argument for function "NONE", expected 1th argument to be one of type: ["number"]." } ] } }`) fixedJSON := fixUnescapedQuotes(rawJSON) var data map[string]interface{} if err := json.Unmarshal(fixedJSON, &data); err != nil { fmt.Println("解析失败:", err) return } fmt.Println("解析成功:") prettyJSON, _ := json.MarshalIndent(data, "", " ") fmt.Println(string(prettyJSON)) }
BigQuery解决方案
BigQuery内置正则无法处理复杂JSON嵌套场景,建议使用JavaScript UDF预处理非法JSON:
CREATE TEMP FUNCTION FixUnescapedJSON(json_str STRING) RETURNS STRING LANGUAGE js AS """ function fixQuotes(s) { let inString = false; let inEscape = false; let result = []; for (let c of s) { if (c === '\\') { inEscape = !inEscape; result.push(c); } else if (c === '"' && !inEscape) { if (inString) { // 检查前一个非空白字符是否为冒号,判断是否是字段值结束引号 let lastNonSpace = ''; for (let i = result.length - 1; i >= 0; i--) { if (![' ', '\t', '\n', '\r'].includes(result[i])) { lastNonSpace = result[i]; break; } } if (lastNonSpace !== ':') { result.push('\\'); } } inString = !inString; result.push(c); } else { inEscape = false; result.push(c); } } return result.join(''); } try { let fixed = fixQuotes(json_str); JSON.parse(fixed); return fixed; } catch (e) { return null; } """; -- 使用示例 SELECT FixUnescapedJSON('{ "obj1": "value is "test" of test, \"obj1\" val", "result": "your result is "out" in our website", "info": { "x": [ { "desc": "shjjfdsajfjkfsdkf, "sfsdfsdfdsf" fjkdfgjkfd." } ] } }') AS fixed_json;
关键提醒
永远不要用正则表达式处理JSON——JSON的嵌套结构、转义规则无法通过正则的上下文无关语法正确处理,状态机或专门的修复工具才是可靠方案。
内容的提问来源于stack exchange,提问作者jonathan
相关产品推荐
相关产品推荐

