FormatArc JSON 格式化器解析已移除尾隨逗號的 JSON 結果畫面FormatArc JSON 格式化器解析已移除尾隨逗號的 JSON 結果畫面
作者: FormatArc 編輯部發布日期: 2026-09-02更新日期: 2026-09-02

JSON 尾隨逗號:找出位置、刪除、一次修好

JSON 尾隨逗號是什麼

尾隨逗號(trailing comma)是物件或陣列的最後一個元素之後、結尾括號 }] 前方殘留的逗號。標準 JSON(RFC 8259)不允許這種寫法,嚴格的解析器會以 Unexpected token }Expecting property name enclosed in double quotes 之類的錯誤拒絕整個檔案。修法就是刪掉那一個逗號。

這篇文章只講尾隨逗號(,)的問題,不談 ///* */ 註解。JSON 註解是另一篇主題,詳見 JSON 註解方式。這裡專注於:為什麼會報錯、怎麼定位、怎麼修、以及 JSON5 和 JSONC 的差異在哪裡。

在瀏覽器中直接修

如果你只想盡快讓錯誤消失,不需要手動數字符。

  1. 開啟 JSON 格式化器
  2. 把解析失敗的 JSON 貼上
  3. 讀取顯示的錯誤行號。它指向多餘逗號後面的那個結尾括號
  4. 刪掉該 }] 前方緊鄰的逗號,再按一次執行
  5. 從輸出區複製整理好的 JSON

格式化全程在瀏覽器中執行。你貼上的 JSON 不會被上傳、記錄或儲存。處理 API 回應或包含內部資料的設定檔案時,這一點很重要。

FormatArc JSON 格式化器顯示已整理 JSON 的畫面FormatArc JSON 格式化器顯示已整理 JSON 的畫面

修前與修後

尾隨逗號出現的位置有兩種:物件和陣列。以下逐一比較。

物件的尾隨逗號:

{
  "name": "Aoi",
  "role": "Engineer",
}
{
  "name": "Aoi",
  "role": "Engineer"
}

陣列的尾隨逗號:

[
  "red",
  "green",
  "blue",
]
[
  "red",
  "green",
  "blue"
]

巢狀結構中,內側物件或陣列也可能藏著尾隨逗號:

{
  "tags": ["a", "b",],
  "meta": {
    "active": true,
  }
}
{
  "tags": ["a", "b"],
  "meta": {
    "active": true
  }
}

不管哪種情況,修法都一樣:把最後一個值與結尾括號之間的逗號刪掉。值本身沒有問題。

你會看到的錯誤訊息

同樣的尾隨逗號,不同語言的解析器用詞不同。

瀏覽器與 Node.js(V8)的 JSON.parse

SyntaxError: Unexpected token } in JSON at position 42
SyntaxError: Expected double-quoted property name in JSON at position 42

Python 的 json.loads

json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes: line 4 column 1 (char 42)

共同點是:解析器讀到逗號後期待下一個值或鍵,結果等來的卻是結尾括號。大多數解析器回報的位置或行號是結尾括號 } / ] 的位置,所以該刪的逗號在上一行(Python 是例外,它指向逗號本身,後面的表格會看到)。

把同一份輸入實際餵給五種解析器,可以看到位置標示的差異有多大(實測:scripts/benchmarks/json-trailing-comma/,2026-08-17,Node.js v26.7.0 / Python 3.14.6 / jq 1.7.1-apple / json5 2.2.3 / jsonc-parser 3.3.1)。輸入是以下多行物件:

{
  "a": 1,
  "b": 2,
}
解析器尾隨逗號的處理方式
V8 (Node.js) JSON.parse拒絕。Expected double-quoted property name in JSON at position 22 (line 4 column 1)
Python json.loads拒絕。Illegal trailing comma before end of object: line 3 column 9 (char 20)
jq拒絕。jq: parse error: Expected another key-value pair at line 4, column 1
JSON5接受(無錯誤)
jsonc-parser拒絕。PropertyNameExpected at offset 22; ValueExpected at offset 22

位置標示因解析器而異。V8 和 jsonc-parser 指向結尾括號的位置(offset 22 / line 4 column 1),jq 指向括號所在的行,只有 Python 指向逗號本身(line 3 column 9)。

如果錯誤訊息出現了卻找不到逗號在哪,貼到 JSON 格式化器 就會標示出對應行。各種 JSON 解析錯誤的原因與修法,詳見 JSON 解析錯誤的原因與修法

為什麼 JSON 禁止尾隨逗號

RFC 8259在新分頁中開啟 定義逗號是值與值之間的分隔符(separator),不是每個值之後的終止符(terminator)。Section 2 的文法將陣列定義為「逗號分隔的值序列」、物件定義為「逗號分隔的成員序列」,最後一個值之後不允許再放元素。因此只有空白和結尾括號跟隨的逗號沒有分隔對象,符合規格的解析器必須拒絕它。

這個失誤也因為一個原因特別常出現:JavaScript 的物件與陣列字面量允許尾隨逗號,很多編輯器會照此格式整理 .js 檔案。但 JSON.parse() 讀的是嚴格 JSON 而非 JavaScript。在 .js 檔案中沒問題的文字,一旦被當作 JSON 解析就會失敗。把程式碼中的物件複製到 .json 檔案是尾隨逗號混入的最典型路徑。其他嚴格 JSON 的語法規則,詳見 JSON 格式是什麼

自動移除尾隨逗號

手動刪一個逗號很快,但如果要處理的是 JSON 產生程式碼或大量檔案,就應該自動化。

用序列化器產生 JSON,不要用字串拼接。JSON.stringify(以及各語言的等效功能)不會輸出尾隨逗號,從源頭避免問題:

const data = { name: "Aoi", role: "Engineer" };
const json = JSON.stringify(data, null, 2);
// 永遠有效 — 絕不會產生尾隨逗號

儲存時自動整理。在 VS Code 中對 .json 檔案執行 Format Document(或 Prettier 的 format-on-save),重排格式的過程會移除尾隨逗號。這是保持手動編輯的設定檔案乾淨最簡單的方法。

正規表示式是最後手段。,\s*([}\]]) 匹配逗號加空白加結尾括號:

const cleaned = source.replace(/,(\s*[}\]])/g, "$1");
const data = JSON.parse(cleaned);

只能當作備用方案。它可能誤傷字串值中的逗號(例如 "a,}"),所以只用在你能掌控的檔案上,處理完用 JSON 格式化器 驗證結果。

解析器選項只負責「接受」,不負責「改寫」。有些函式庫可以容忍尾隨逗號(例如 .NET 的 JsonSerializerOptions.AllowTrailingCommas)。這些選項讓你的程式碼讀檔案不報錯,但不會更改磁碟上的檔案,也不會讓其他嚴格解析器接受它。如果 JSON 要傳給其他服務,還是得把逗號刪掉。

用 Python 批次移除

標準函式庫 json 不接受尾隨逗號,但 json5 套件可以按 JSON5 規格(允許尾隨逗號)來解析。走的是真正的解析器,不像正規表示式可能誤碰字串值中的 ,}

# pip install json5
import json, json5

with open("broken.json") as f:
    data = json5.load(f)

with open("fixed.json", "w") as f:
    json.dump(data, f, ensure_ascii=False, indent=2)

用 Node.js 批次移除

用 npm 的 json5 套件讀入,再用標準 JSON.stringify 寫回:

// npm install json5
import JSON5 from "json5";
import fs from "node:fs";

const data = JSON5.parse(fs.readFileSync("broken.json", "utf8"));
fs.writeFileSync("fixed.json", JSON.stringify(data, null, 2));

用 sed 一次處理多個檔案

CI 管線或 shell 腳本要一次清理大量檔案時,sed 最方便。但有前述正規表示式的誤傷風險,處理後務必加上解析驗證:

sed -E 's/,[[:space:]]*([}\]])/\1/g' broken.json > fixed.json
python3 -c "import json; json.load(open('fixed.json'))"  # 驗證

jq 修不了的原因

jq 的解析器是嚴格的,包含尾隨逗號的輸入它直接拒絕。jq . broken.json 不會修檔案,而是報錯停止。jq 是用來處理已合法 JSON 的工具,先用上面的方法移除逗號,再用 jq 做後續加工。

避免尾隨逗號再次出現

修好一個檔案不代表下一個不會再犯。以下幾道防線可以早抓:

  • 編輯器:VS Code 對 .json 檔案的尾隨逗號會顯示警告(.jsonc 則不顯示)。保持副檔名為 .json 讓警告維持開啟
  • 知道高發位置:尾隨逗號最常出現在手動編輯的設定檔、從 .js 原始碼複製過來的 JSON、以及用字串拼接組裝的 JSON。真正序列化器產生的 JSON 是安全的

trailingComma 是從哪來的

儲存時的自動格式化可能是尾隨逗號回流的元兇。Prettier 官方文件與 issue tracker 記載如下:

項目內容出處
Prettier 預設值trailingComma 自 v3.0.0 起預設為 "all",此前是 "es5"prettier.io/docs/options在新分頁中開啟
VS Code 擴充強制關閉 trailingComma 的是 VS Code 擴充本身而非 Prettier 核心,且只在解析器為 json 時生效 — 變更請求的 issue 已關閉並鎖定prettier-vscode#589在新分頁中開啟
tsconfig.json即使副檔名是 .json,Prettier 核心會推斷此檔為 JSONC,儲存時可能補上尾隨逗號 — 已關閉且標記為不處理prettier#15942在新分頁中開啟
.jsonc 整體相同的 JSONC 推斷也適用於所有 .jsonc 副檔名的檔案 — issue 仍為 openprettier#15956在新分頁中開啟

在 CI 中加一道 JSON.parse 關卡

JSON 支援的 linter 或建置流程中的 JSON.parse 步驟,可以在尾隨逗號被送到下游服務前截住。不需任何相依的最小寫法:

node -e "JSON.parse(require('fs').readFileSync(process.argv[1], 'utf8'))" config.json

把它掛到 pre-commit hook,或在 CI 中對儲存庫內所有 .json 檔案迴圈執行。手動編輯的設定檔尤其值得加,因為那正是尾隨逗號最容易回流的所在位置。

JSON5 與 JSONC 允許尾隨逗號

如果你為了 diff 乾淨而堅持要保留尾隨逗號,有支援的格式。

  • JSON5 是具正式規格的 JSON 超集合,無條件允許尾隨逗號、註解、未加引號的鍵、單引號。實測的五種解析器中唯一 accepted: true 且零錯誤的就是它(scripts/benchmarks/json-trailing-comma/
  • JSONC(VS Code 使用的「含註解 JSON」)在 JSON 基礎上加了註解。其 jsonc-parser 實作採寬容恢復(lenient recovery)策略:遇到尾隨逗號不會丟例外,仍會回傳值,但會把該尾隨逗號記入 errors 陣列(見上方表格 jsonc-parser 那一行)。回傳值和被正式接受是兩回事,VS Code 設定檔「允許」尾隨逗號指的是前者

要注意的是適用範圍。如果是由理解這些擴充格式的工具讀取的設定檔,完全沒問題。但作為 API 酬載、package.json、或使用嚴格 JSON.parse 的服務,尾隨逗號不合法。

如果你的目標只是乾淨易讀的嚴格 JSON,把結果丟到 JSON 格式化器 確認即可。排版上的具體技巧詳見 JSON 排版線上工具

常見問題

JSON 能使用尾隨逗號嗎?

不能。RFC 8259 將逗號定義為值與值之間的分隔符,最後一個值之後不允許再放元素。結尾括號 }] 前的逗號無效,嚴格解析器會以 Unexpected token } 等錯誤拒絕。

怎麼找到並移除尾隨逗號?

把 JSON 貼到 JSON 格式化器。錯誤訊息指向多餘逗號後面的結尾括號,刪掉該行逗號再執行一次即可。要根本防止的話,用 JSON.stringify 產生 JSON,不要手動拼字串。

為什麼 JavaScript 可以用尾隨逗號,JSON 卻不行?

JavaScript 的物件與陣列字面量允許尾隨逗號是語言上的便利設計。JSON 是 JSON.parse 讀取的嚴格資料格式,遵循 RFC 8259,最後一個值之後沒有放元素的規則。同一份文字作為 JS 字面量合法,作為 JSON 則不合法。

尾隨逗號會產生什麼錯誤訊息?

V8 / Node 多數是 Unexpected token }(或 ]),較新 V8 是 Expected double-quoted property name,Python 是 Expecting property name enclosed in double quotes。意思都是:解析器在期待下一個值或鍵的位置看到了結尾括號。

不刪掉、直接設定允許尾隨逗號行不行?

有些解析器可以設定為容忍(例如 .NET 的 AllowTrailingCommas)。但那只是讓讀檔案那端的程式碼不報錯,不會讓檔案本身對其他解析器或傳輸過程有效。要能互通的 JSON,還是得刪掉逗號。

JSON5 中尾隨逗號能正常使用嗎?

可以。JSON5 明確允許尾隨逗號,同時接受註解與未加引號的鍵。適合本地設定檔,但不適用於需要嚴格 RFC 8259 JSON 的 API 資料。

總結

  • 尾隨逗號是結尾括號 } / ] 前方的逗號,標準 JSON 禁止
  • 錯誤形式為 Unexpected token }Expecting property name enclosed in double quotes。回報位置是括號,所以逗號在前一行
  • 最快的修法:貼到 JSON 格式化器,讀行號,刪逗號
  • JSON.stringify 產生並搭配儲存時格式化,可以防止尾隨逗號回流
  • JSON5 / JSONC 允許尾隨逗號,但只限理解這些格式的工具有效,API 酬載中不能使用