You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修复Go语言JSON校验代码中行尾错误的行号定位偏差

修复JSON语法错误位置检测的行号偏移问题

问题根源

原代码存在两个核心问题:

  1. 错误使用decoder.InputOffset()获取位置:该值是解码器已成功读取的字节数,而非错误实际发生的位置。当行尾缺失逗号时,解码器会继续读取后续内容才触发错误,导致位置指向后续行。
  2. 行号列号计算逻辑未准确匹配错误偏移的归属行,对行尾位置的判断存在偏差。

修复后的代码

package main

import (
	"encoding/json"
	"fmt"
	"io"
	"strings"
)

func main() {
	input := `{
  "a": 1
  "b": 2
}`
	decoder := json.NewDecoder(strings.NewReader(input))
	decoder.UseNumber()

	var err error
	for {
		if _, err = decoder.Token(); err != nil {
			break
		}
	}

	if err != nil {
		if err == io.EOF {
			fmt.Println("JSON is valid")
		} else {
			// 断言错误为JSON语法错误,获取精确偏移量
			syntaxErr, ok := err.(*json.SyntaxError)
			if !ok {
				fmt.Printf("JSON parsing error: %v\n", err)
				return
			}
			errorOffset := int(syntaxErr.Offset)
			jsonLines := strings.Split(input, "\n")
			currentOffset := 0
			line := 1
			character := 1

			for _, lineContent := range jsonLines {
				lineLen := len(lineContent)
				// 判断错误偏移是否落在当前行范围内(包含行尾)
				if currentOffset+lineLen >= errorOffset {
					character = errorOffset - currentOffset + 1 // 列号从1开始计数
					break
				}
				// 累加当前行长度+换行符(1字节)
				currentOffset += lineLen + 1
				line++
			}

			fmt.Printf("JSON is invalid at line %d, character %d: %v\n", line, character, syntaxErr)
		}
	}
}

修复说明

  1. 获取精确错误偏移:将解析错误断言为*json.SyntaxError,直接使用其Offset字段,该值是JSON规范定义的错误发生精确位置,而非解码器已读取的滞后位置。
  2. 修正行号列号计算:逐行累加字节偏移量,判断错误偏移是否属于当前行内容范围(从当前行起始偏移到行尾)。如果是,直接计算列号;否则进入下一行。这种逻辑能准确将行尾缺失逗号的错误归属到错误实际发生的行,而非后续行。

内容的提问来源于stack exchange,提问作者rubypoe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 01:52:25