Fixer for broken/unescaped quotes in pseudo-JSON text
Project description
jsonfixer
A small utility to repair broken / pseudo-JSON strings that AI models often
produce, so they can be parsed by Python's built-in json module.
Motivation
LLM outputs frequently contain JSON that looks correct but is actually invalid:
- Unescaped inner double quotes inside string values
- Raw control characters (literal newlines, tabs, etc.) inside strings
- Smart/curly quotes (
“ ” ‘ ’) instead of straight quotes - The whole JSON wrapped in Markdown triple-backtick code fences
- The whole JSON returned as a quoted string with escaped
\nsequences
For example, the following is not valid JSON and json.loads will fail:
{
"key1": "value1",
"key2": "value2 is behind the "value1", that is good"
}
jsonfixer detects and repairs these common patterns so you can reliably
call json.loads() on the result.
Features
- Escapes stray inner double quotes inside string values (
"→\") - Converts literal control characters inside strings to proper JSON escapes
(
\n,\t,\r,\b,\f, and\u00XXfor other< 0x20code points) - Normalizes CRLF (
\r\n) inside strings to\n - Optional extraction of JSON from Markdown code fences (
```json ... ```) - Optional replacement of smart quotes (
“ ” ‘ ’) with straight quotes (" ') - Leaves already-valid JSON unchanged
- Pure Python, no runtime dependencies
Installation
pip install jsonquotefixer
Usage
Basic example
import json
from jsonfixer import fix_quotes
broken = '{"title": "The "Great" Gatsby", "author": "F. Scott Fitzgerald"}'
json.loads(broken) # raises json.JSONDecodeError
fixed = fix_quotes(broken)
json.loads(fixed)
# {'title': 'The "Great" Gatsby', 'author': 'F. Scott Fitzgerald'}
Extracting from a Markdown code block
Pass parse_code=True when the model wraps the JSON in triple backticks,
or returns it as a JSON-encoded string with escaped newlines:
from jsonfixer import fix_quotes
raw = '```json\n{"a": "hello"}\n```'
fix_quotes(raw, parse_code=True)
# '{"a": "hello"}'
Replacing smart quotes
Pass replace_smart=True to convert curly quotes to straight quotes before
the fix-up step runs:
from jsonfixer import fix_quotes
raw = '{“a”: “hello”}'
fix_quotes(raw, replace_smart=True)
# '{"a": "hello"}'
All options combined
fix_quotes(raw, parse_code=True, replace_smart=True)
API
fix_quotes(s, parse_code=False, replace_smart=False) -> str
Main entry point. Returns a repaired JSON string.
| Argument | Type | Default | Description |
|---|---|---|---|
s |
str |
— | The broken / pseudo-JSON string to repair. |
parse_code |
bool |
False |
Extract JSON from Markdown code fences, and unwrap outer JSON string quotes. |
replace_smart |
bool |
False |
Replace smart quotes (“ ” ‘ ’) with straight quotes (" ') before fixing. |
parse_codeblock(s) -> str | None
Extracts the content of the first triple-backtick code fence in s
(with or without a language tag). Also handles the case where newlines
appear as the literal two-character sequence \n. Returns None if no
code fence is found.
replace_smart_quotes(s) -> str
Returns s with smart quotes replaced by their straight-quote equivalents.
Does not perform any other repair.
Development
Setting up
git clone https://github.com/abzb1/jsonfixer.git
cd jsonfixer
pip install -e '.[dev]'
Running the tests
Tests are written with pytest:
pytest
Or, to run a specific test and see verbose output:
pytest tests/test_fix_quotes.py -v
pytest tests/test_fix_quotes.py::test_valid_json_unchanged -v
Pre-commit hooks
The repository ships with a .pre-commit-config.yaml. Enable it with:
pre-commit install
pre-commit run --all-files
License
MIT — see LICENSE.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file jsonquotefixer-0.3.0.tar.gz.
File metadata
- Download URL: jsonquotefixer-0.3.0.tar.gz
- Upload date:
- Size: 7.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
eb67ab088442ae57c4dc41778688339cd7d223beac5068023cf72cd0e4c1f006
|
|
| MD5 |
a2b625a0c6b0874d893c63fdb0f4a7a9
|
|
| BLAKE2b-256 |
8b059e2359c5f7caf6f4924038bcc200f9b86c44541917aef9c41c76795c1e49
|
File details
Details for the file jsonquotefixer-0.3.0-py3-none-any.whl.
File metadata
- Download URL: jsonquotefixer-0.3.0-py3-none-any.whl
- Upload date:
- Size: 5.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a15fb6317ba20f1c9a03258a6a32b81385c4096814992651e3f8c13d4327c6a7
|
|
| MD5 |
c40836764e370dac19c69e94e95e3f99
|
|
| BLAKE2b-256 |
22a95e82b5a2a9415a28123e6d19c5ee5cda3b9665908e42ca6b0597c74bf8ef
|