@@ -530,8 +530,12 @@ static byte[] decode(String hex) {
530
530
531
531
/**
532
532
* A regex pattern of a line in a CSV file.
533
+ * (?<=^|,): start of line or comma
534
+ * (?=")("[^"].*?(?<!")"),: matches a quoted string, ignoring double quotes
535
+ * (?!")(.*?): matches a non-quoted string
536
+ * (,|$): end of line or comma
533
537
*/
534
- private static final Pattern CSV_LINE_PATTERN = Pattern .compile ("(?<=^|,)\\ s*([^ \" ,]*| \" ( [^\" ]| \" \" )* \" )\\ s*(,|$)" );
538
+ private static final Pattern CSV_LINE_PATTERN = Pattern .compile ("(?<=^|,)\\ s*(?:(?= \" )( \" [^\" ].*?(?<! \" ) \" )|(?! \" )(.*?) )\\ s*(,|$)" );
535
539
536
540
/**
537
541
* Splits the given CSV line into its values.
@@ -544,32 +548,16 @@ static byte[] decode(String hex) {
544
548
@ Nullable
545
549
static String [] splitCSV (String line ) {
546
550
551
+ Matcher matcher = CSV_LINE_PATTERN .matcher (line );
547
552
548
553
int lastEnd = 0 ;
549
554
ArrayList <String > result = new ArrayList <>();
550
555
551
- // avoid regex matching quoted var names
552
- if (line .startsWith ("\" " )) {
553
- // find closing quote '",'
554
- int start = 0 ;
555
- while (start < line .length () && (start == 0 || line .charAt (start - 1 ) == '"' )) {
556
- start = line .indexOf ("\" ," , start + 2 );
557
- if (start == -1 ) {
558
- // No closing quote found
559
- return null ;
560
- }
561
- }
562
- result .add (line .substring (1 , start ).replace ("\" \" " , "\" " ));
563
- lastEnd = start + 2 ;
564
- }
565
-
566
- Matcher matcher = CSV_LINE_PATTERN .matcher (line );
567
-
568
556
while (matcher .find (lastEnd )) {
569
557
if (lastEnd != matcher .start ())
570
558
return null ; // other stuff inbetween finds
571
559
572
- String value = matcher .group (1 );
560
+ String value = matcher .group (1 ) != null ? matcher . group ( 1 ) : matcher . group ( 2 ) ;
573
561
if (value .startsWith ("\" " ))
574
562
// Unescape value
575
563
result .add (value .substring (1 , value .length () - 1 ).replace ("\" \" " , "\" " ));
0 commit comments