CSV Regex пропустив первую запятую - PullRequest
0 голосов
/ 04 мая 2020

Я использую регулярное выражение для обработки CSV, где данные могут быть в кавычках или без кавычек. Но если в начальном столбце есть только запятая, она пропускает ее.

Вот регулярное выражение, которое я использую: (?:,"|^")(""|[\w\W]*?)(?=",|"$)|(?:,(?!")|^(?!"))([^,]*?|)(?=$|,)

Теперь пример данных, которые я использую: ,"data",moredata,"Data" У которых должно быть 4 совпадения ["", "data", "moredata", "Data"], но всегда пропускается первая запятая. Хорошо, если в первом столбце есть кавычки, или он не пустой, но если он пустой без кавычек, он игнорирует его.

Вот пример кода, который я использую для целей тестирования: Дарт написано:


void main() {

  String delimiter = ",";
  String rawRow = ',,"data",moredata,"Data"';
RegExp exp = new RegExp(r'(?:'+ delimiter + r'"|^")(^,|""|[\w\W]*?)(?="'+ delimiter + r'|"$)|(?:'+ delimiter + '(?!")|^(?!"))([^'+ delimiter + r']*?)(?=$|'+ delimiter + r')');


Iterable<Match> matches = exp.allMatches(rawRow.replaceAll("\n","").replaceAll("\r","").trim());
List<String> row = new List();
matches.forEach((Match m) {
  //This checks to see which match group it found the item in.
  String cellValue;
  if (m.group(2) != null) {
    //Data found without speech marks
    cellValue = m.group(2);
  } else if (m.group(1) != null) {
    //Data found with speech marks (so it removes escaped quotes)
    cellValue = m.group(1).replaceAll('""', '"');
  }  else {
    //Anything left
    cellValue = m.group(0).replaceAll('""', '"');
  }
  row.add(cellValue);
});
  print(row.toString());

}

1 Ответ

0 голосов
/ 12 мая 2020

Расследование вашего выражения

(,"|^")
(""|[\w\W]*?)
(?=",|"$)
|
(,(?!")|^(?!"))
([^,]*?|)
(?=$|,)

(,"|^")(""|[\w\W]*?)(?=",|"$) Эта часть предназначена для соответствия строк в кавычках, которые, кажется, вам подходят

Пройдя через эту часть (,(?!")|^(?!"))([^,]*?|)(?=$|,)
(,(?!")|^(?!")) начинаются с запятой, за которой не следует «ИЛИ начало строки, за которой не следует»
([^,]*?|) Начало строки или ноль запятой или более, не жадные и |, почему |
(?=$|,) конец строки или,.

В CSV эта строка ,,,3,4,5 должна дать 6 совпадений, но приведенное выше получает только 5

. Вы можете добавить (^(?=,)) в начале второй части, той части, которая соответствует разделам без кавычек.
Вторая группа с начальным совпадением, а также добавленный не захват в группы
(?:^(?=,))|(?:,(?!")|^(?!"))(?:[^,]*?)(?=$|,)

Завершено: (?:,"|^")(?:""|[\w\W]*?)(?=",|"$)|(?:^(?=,))|(?:,(?!")|^(?!"))(?:[^,]*?)(?=$|,)

Вот еще одна, которая может работать
(?:(?:"(?:[^"]|"")*"|(?<=,)[^,]*(?=,))|^[^,]+|^(?=,)|[^,]+$|(?<=,)$)
Как это работает, я описал здесь: Создание парсера CSV с использованием регулярных выражений

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...