OK, you've seen from the comments that regex is so not the right tool for this. But if you insist, here goes:
This regex will work in Java (or .NET and other implementations that support possessive quantifiers and verbose regexes):
^ # Start of string
(?: # Match the following:
(?: # Either match
[^",\n]*+ # 0 or more characters except comma, quote or newline
| # or
" # an opening quote
(?: # followed by either
[^"]*+ # 0 or more non-quote characters
| # or
"" # an escaped quote ("")
)* # any number of times
" # followed by a closing quote
) # End of alternation
, # Match a comma (separating the CSV columns)
)* # Do this zero or more times.
(?: # Then match
(?: # using the same rules as above
[^",\n]*+ # an unquoted CSV field
| # or a quoted CSV field
"(?:[^"]*+|"")*"
) # End of alternation
) # End of non-capturing group
$ # End of string
Java code:
boolean foundMatch = subjectString.matches(
"(?x)^ # Start of string\n" +
"(?: # Match the following:\n" +
" (?: # Either match\n" +
" [^\",\\n]*+ # 0 or more characters except comma, quote or newline\n" +
" | # or\n" +
" \" # an opening quote\n" +
" (?: # followed by either\n" +
" [^\"]*+ # 0 or more non-quote characters\n" +
" | # or\n" +
" \"\" # an escaped quote (\"\")\n" +
" )* # any number of times\n" +
" \" # followed by a closing quote\n" +
" ) # End of alternation\n" +
" , # Match a comma (separating the CSV columns)\n" +
")* # Do this zero or more times.\n" +
"(?: # Then match\n" +
" (?: # using the same rules as above\n" +
" [^\",\\n]*+ # an unquoted CSV field\n" +
" | # or a quoted CSV field\n" +
" \"(?:[^\"]*+|\"\")*\"\n" +
" ) # End of alternation\n" +
") # End of non-capturing group\n" +
"$ # End of string");
Be aware that you can't assume that every line in a CSV file is a complete row. You can have newlines within a CSV row (as long as the column containing the newlines is enclosed in quotes). This regex knows this, but it will fail if you feed it only a partial row. Which is yet another reason why you really need a CSV parser to validate a CSV file. That's what parsers do. If you control your input and know that you'll never have newlines inside a CSV field, you might get away with it, but only then.