`json.loads()` / `json.load()` 有個 `strict` 參數,**預設 `True`**。它只管一件事:
**字串值裡能不能出現「未跳脫的控制字元」**——也就是「換行字元本身、tab 字元本身」
(按 Enter/Tab 直接打進去的那個字元),而不是 `\n`、`\t` 這種跳脫寫法。
json.loads(s, *, strict=True) # 預設
一個例子看懂
import json
# 字串值裡有「換行字元本身」(按 Enter 打進去的,不是 \n 跳脫寫法)→ 不合法 JSON
bad = '{"description": "line1\nline2"}'
json.loads(bad) # ❌ JSONDecodeError: Invalid control character...
json.loads(bad, strict=False) # ✅ {'description': 'line1\nline2'}
正確做法是把換行「跳脫」成 \n(兩個字元 \ + n),這樣連 strict=True 都沒問題:
good = '{"description": "line1\\nline2"}' # 合法 JSON
json.loads(good) # ✅ 不必 strict=False
good與bad解析出來的結果完全一樣,差別只在「來源文字合不合法」。strict=False本質就是「寬容地把bad當good來讀」。
什麼是「控制字元」?
ASCII 0x00–0x1F 的不可見字元,常見:

JSON 標準要求它們必須跳脫;直接塞真字元進字串值就是不合法。
三個關鍵觀念
strict只管控制字元——它不會修復其他錯誤(少括號、多逗號、key 沒引號、Extra data…)。那些在True/False下都一樣失敗。- 和
encoding無關——encoding是「bytes → 文字」的解碼(失敗是UnicodeDecodeError);strict是「文字 → JSON」的解析(失敗是JSONDecodeError)。兩個不同階段。 - 救回來的字元還在——
strict=False只是允許解析,不會刪字元。真的換行會變成字串裡的一個\n字元;不想要得自己.replace()。
建議用法
try:
data = json.loads(text) # 先嚴格:乾淨檔正常過
except json.JSONDecodeError:
data = json.loads(text, strict=False) # 失敗才寬鬆:救含控制字元的髒檔
print("⚠️ loaded with strict=False") # 留個痕跡,知道這檔不乾淨為什麼不一開始就 strict=False? 先嚴格能讓「不乾淨的檔」被標記出來(利於追蹤品質);一律寬鬆會把問題悄悄吞掉, 而且對非控制字元的錯誤根本沒幫助。
一句話總結
strict=False = 「允許字串內含未跳脫的控制字元」。只放寬這一條,其餘 JSON 規則照舊。 能產出合法 JSON 最好,就完全用不到它。
推薦hahow線上學習python: https://igrape.net/30afN




![Python 讀取 DOCX 圖片關聯:qn+find/findall 與 XPath 的實戰對照 from lxml import etree ; from docx.oxml.ns import qn; lxml.etree._Element.findall( f”.//{ qn(‘a:blip’) }” ) ; .get( qn(“r:embed”) ) #獲取 屬性名 ‘r:embed’ 的 屬性值(如: ‘rId4’) ; lxml.etree._Element.xpath( “//a:blip/@r:embed”, namespaces = NS) #/@r:embed = 獲取 屬性名 ‘r:embed’ 的 屬性值(如: ‘rId4’),使用.findall() 要先.findall()獲取List[_Element],再迴圈_Element.get()獲取屬性值, .xpath() 第一個參數path 使用”//a:blip/@r:embed” ,可直接獲取屬性值(List[str]如: [‘rId4’, ‘rId5’]) ; 如何對docx真實移除圖片瘦身? Python 讀取 DOCX 圖片關聯:qn+find/findall 與 XPath 的實戰對照 from lxml import etree ; from docx.oxml.ns import qn; lxml.etree._Element.findall( f”.//{ qn(‘a:blip’) }” ) ; .get( qn(“r:embed”) ) #獲取 屬性名 ‘r:embed’ 的 屬性值(如: ‘rId4’) ; lxml.etree._Element.xpath( “//a:blip/@r:embed”, namespaces = NS) #/@r:embed = 獲取 屬性名 ‘r:embed’ 的 屬性值(如: ‘rId4’),使用.findall() 要先.findall()獲取List[_Element],再迴圈_Element.get()獲取屬性值, .xpath() 第一個參數path 使用”//a:blip/@r:embed” ,可直接獲取屬性值(List[str]如: [‘rId4’, ‘rId5’]) ; 如何對docx真實移除圖片瘦身?](https://i2.wp.com/savingking.com.tw/wp-content/uploads/2025/11/20251119130848_0_3fbf6b.png?quality=90&zoom=2&ssl=1&resize=350%2C233)

![Python: Regular Expression 正規表示法 正則表達式 import re ; pattn = “[\d]{4}\/[01][\d]\/[0123][\d] [\d]{6}” ; match = re .search (pattn,text) .group() Python: Regular Expression 正規表示法 正則表達式 import re ; pattn = “[\d]{4}\/[01][\d]\/[0123][\d] [\d]{6}” ; match = re .search (pattn,text) .group()](https://i2.wp.com/savingking.com.tw/wp-content/uploads/2022/09/20220901154435_19.png?quality=90&zoom=2&ssl=1&resize=350%2C233)
![Python: pandas.DataFrame的串接 pandas.concat() #concatenate 連接, 如何重新排列columns 順序? df[[“甲”, “乙”, “丙”]] ; df.reindex( columns = [“甲”, “乙”, “丙”] ) Python: pandas.DataFrame的串接 pandas.concat() #concatenate 連接, 如何重新排列columns 順序? df[[“甲”, “乙”, “丙”]] ; df.reindex( columns = [“甲”, “乙”, “丙”] )](https://i0.wp.com/savingking.com.tw/wp-content/uploads/2023/05/20241120092030_0_98dff3.png?quality=90&zoom=2&ssl=1&resize=350%2C233)


近期留言