I've been trying to parse some csv files (which I have no control over how they are written) using python's provided csv library. However, I am having trouble getting it right, it works for the standard cases, but it chokes in some other cases.
The csv files seem to follow some conventions
- minimal double quoting, so when there is no special characters in a text field, no double quotes
- Certain fields however are always quoted, even when empty.
- These certain fields, when there are special characters, are double double quoted
- When quotes are within these certain fields, they are escaped with a double quote
As an example:
USER NAME,@SOME_ACCOUNT#1234,18363,"",
USER NAME 2,@SOME_ACCOUNT_2#1234,18363,"A normal comment",
ANOTHER USER,@ANOTHER ACCOUNT#5678,27110,""A user provided string, with a comma"",AnOptionalField
YAU,@YAA#XYZ,88482,""""A user provided string with quotes"" "",AnOptionalField
I've been trying these settings:
def get_csv_records(iterable):
return list(DictReader(iterable
, escapechar="\""
, doublequote=True
, delimiter=","
, quoting=QUOTE_MINIMAL))
But in the 3nd case, it fails by putting the OptionalField in with the comment field, so it chokes on that comma in the comment.
I've tried using a regex to escape commas with a backslash \, and using escapechar="\\", but then the comment looks like the comment, with a comma"", it trims off the first quotes, but not the last 2.
I haven't messed with the last case yet, I'm still trying to get the 3rd to pass.
Any advice on what parameters or dialect I should use?
Any documentation on how to subclass a Dialect? The documentation doesn't say much as far as examples goes Dialects docs
I think I might just have to write a custom parser maybe, or do some trickery with more regexes to "fix" the files to conform to python's parser.
EDIT:
I'm not sure there is an answer to, "What are the correct parameters...?", that the csv lib will accept for this particular csv formatting, but if there is I'd be interested to know.
I did try the CleverCSV library, but it had the same problems.
What I ended up doing was some naive search and replace using a combination of simple regex's to make the lines conform to a set of parameters that the csv library parser will accept. In particular, I undouble-double quoted the quotes, and used \ as an escape character to escape "inner" quotes and commas. I don't like the solution, it probably is fairly brittle, so I'll need to test it thoroughly.