CSV dialects and validation
When a CSV File Uses Semicolons or Tabs Instead of Commas
Identify the actual delimiter in a CSV export, configure its import explicitly, and convert a known semicolon dialect without changing data commas.
A file named .csv may contain semicolon-separated or tab-separated records because the exporting application used a different dialect. First inspect the content and the export settings. Do not replace punctuation throughout the file until you know which characters separate fields and which belong inside the data.
Identify the stored structure
If the header is id;name;amount and the records follow the same pattern, a semicolon delimiter is a reasonable hypothesis. Test it with a CSV-aware importer and verify the resulting columns. A text editor can reveal visible semicolons, but quoted fields may also contain those characters as data.
Tab-separated text can look like aligned columns without showing the separator visibly. Use an editor’s whitespace display or an importer that offers Tab as a delimiter. Do not infer the format solely from how neatly the text appears in one font or window size.
Import with an explicit delimiter
Choose the importer’s delimiter and quote settings to match the file, then inspect the preview. Check the expected number of columns, the header labels and a record containing punctuation. If every row appears in one column, the selected delimiter may be wrong, but that symptom alone does not identify the correct replacement.
Some exports use a decimal comma and a semicolon between fields. For example, the text 12,50 can remain one amount field when the delimiter is a semicolon. Replacing every comma would damage the decimal representation instead of fixing the table.
Convert a known semicolon dialect
The following Python example assumes semicolons are the actual field delimiter and double quotes use the standard CSV escaping convention. It validates consistent record width before creating comma.csv, then parses the new file to check that the values survived.
import csv
with open("input.csv", encoding="utf-8-sig", newline="") as source:
rows = list(csv.reader(source, delimiter=";", strict=True))
if not rows or not rows[0]:
raise ValueError("Expected a header row")
if any(len(row) != len(rows[0]) for row in rows):
raise ValueError("Inconsistent record width")
with open("comma.csv", "w", encoding="utf-8", newline="") as target:
csv.writer(target, delimiter=",", lineterminator="\n").writerows(rows)
with open("comma.csv", encoding="utf-8", newline="") as check:
assert list(csv.reader(check, strict=True)) == rows
For a record containing 00123;"Rao, Anika";12,50, the comma-delimited output quotes the name and the amount as needed. The identifier stays a string. This changes the serialization convention without stripping punctuation from the original values.
Treat automatic detection as a hypothesis
A delimiter detector can suggest a likely dialect from a sample, but a short or unusual file can be ambiguous. A sample containing several punctuation characters at regular intervals may support more than one interpretation. Verify the detected result against known headers and complete field values.
Ask the data producer for the export settings when the format cannot be established confidently. An empty file or a one-column table may not contain enough information to infer a separator. A guess should not become an undocumented transformation of the only source copy.
Separate delimiter changes from data conversion
Changing semicolons to commas through a CSV reader and writer does not convert decimal-comma strings into numeric values, standardize dates or repair incorrect text encoding. Those are separate transformations with their own expected results. Keep the scope narrow so a successful delimiter conversion does not conceal an unrelated value change.
Likewise, adding a .csv extension to tab-separated content does not change its stored separators. Choose an export format the receiver supports, or document the delimiter it should use when importing the existing file.
Verify a second record and the original file
Test a different record containing an embedded semicolon inside a quoted field and a blank final value. Confirm that the quoted semicolon remains within its field and the final empty column survives. Check that the original file remains byte-for-byte unchanged after conversion.
Finally, import comma.csv through the receiving application using the intended settings. Review field types as well as boundaries, particularly for identifiers and dates. The parser round trip proves the chosen string values survived serialization; it does not control a spreadsheet’s later type inference.
Dialect reference
Python’s CSV documentation describes delimiter, quote and reader settings used in this explicit conversion.


