Validate decimal-looking CSV fields without changing them
Quick answer
Validate the text that a CSV parser supplies before converting a quantity to a number. That preserves evidence such as a surrounding space or an unsupported decimal separator. A lexical rule can reject those spellings without guessing whether 12,50 should be repaired, split into two columns, or interpreted under another locale.
Example
The fixture is parsed through csv.DictReader, then the code tests each quantity string with fullmatch. Quoting keeps 12,50 in one CSV field, so it reaches the lexical rule intact and is reported rather than repaired as a locale-specific decimal. The valid 12.50 assertion confirms the normal parser and rule path.
import csv
import io
import re
DECIMAL = re.compile(r"\d+\.\d{2}")
csv_text = "id,quantity\n1,12.50\n2,\"12,50\"\n3, 12.50 \n4,12\n"
rows = list(csv.DictReader(io.StringIO(csv_text, newline="")))
invalid = [row["quantity"] for row in rows if not DECIMAL.fullmatch(row["quantity"])]
assert rows[0]["quantity"] == "12.50"
assert invalid == ["12,50", " 12.50 ", "12"]
print("invalid:", invalid)
Expected stdout:
invalid: ['12,50', ' 12.50 ', '12']
Reading the result
This narrow pattern permits only non-negative values with exactly two fraction digits and a dot. It is not a general money parser: signed quantities, integer quantities, other scales, thousands separators, and localized formats need their own declared policy. Do not strip or replace punctuation during validation, because that changes the raw value on which the finding is based.
Run structural CSV checks before field-level validation in a broader preflight. A row-width mismatch is a different finding from a quoted, well-formed field that fails this decimal spelling rule.
Sources
- Python csv.DictReader documentation
- Python re.Pattern.fullmatch documentation
Prepared with AI assistance. The example uses synthetic data; its stated limits apply.
Comments
Post a Comment