powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / TRegExpr, csv
21 сообщений из 21, страница 1 из 1
TRegExpr, csv
    #39740304
aford
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Всем привет! Знаю, что парсить CSV файлы регулярными выражениями не есть хорошая идея, но очень надо.

Выражение
автор RegExp.Expression := '(,|,\s)*?(.*?)(,|$)';


Строка
авторvalue 1, value 3
value 4, value 5, value 6


Результат
авторvalue 1
value 3

value 4
value 5
value 6


Все устраивает, но в csv бывают строки вида "sas (ыфыф, sasas,)" и парсер ломается. Изъезженная тема, но готового решения я пока не нашел. Как мне сделать, чтобы в тексте
авторvalue 1,sasasas (sasas,sasas sas,s s, asasas), value 3
value 4, value 5, value 6
Программа отрабатывала не так
авторvalue 1
sasasas (sasas
sasas sas
s s
asasas)
value 3

value 4
value 5
value 6


а вот так?
авторvalue 1
sasasas (sasas,sasas sas,s s, asasas)
value 3
value 4
value 5
value 6
...
Рейтинг: 0 / 0
TRegExpr, csv
    #39740321
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
aford,

ИМХО тут реально лучше конечный автомат использовать, потому что для RegExp в этом случае потребутся lookbehind конструкции, а они а) не всеми движками поддерживаются и б) медленные.
...
Рейтинг: 0 / 0
TRegExpr, csv
    #39740347
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Там и код-то элементарный, чтобы с RegEx заморачиваться
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
type
  TOnValue = procedure (const Value: string);

procedure SplitValues(Source: PChar; OnValue: TOnValue);

  procedure DoValue(VLen: Integer);
  var
    Value: string;
  begin
    SetString(Value, Source, VLen);
    OnValue(Value);
    Inc(Source, VLen + 1);
  end;

var
  Cursor: PChar;
  Skip: Integer;
begin
  Skip := 0;
  Cursor := Source;
  repeat
    case Cursor^ of
      #0: Break;
      '(': Inc(Skip);
      ')': if Skip > 0 then
             Dec(Skip);
      ',', #13, #10:
        if Skip = 0 then
        begin
          DoValue(Cursor - Source);
          if Source^ in [#9, #10, #13, #32] then
            Inc(Source);
          Cursor := Source;
        end;
    end;
    Inc(Cursor);
  until False;
  if Cursor > Source then
    DoValue(Cursor - Source);
end;


var
  TestValues: string =
    'value 1,sasasas (sasas,sasas sas,s s, asasas), value 3' + sLineBreak +
    'value 4, value 5, value 6';

procedure OnValue(const Value: string);
begin
  WriteLn('Value: ' + Value);
end;

begin
  SplitValues(PChar(TestValues), OnValue);
  ReadLn;
end.
 

...
Рейтинг: 0 / 0
TRegExpr, csv
    #39740363
aford
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
alekcvp,
спасибо, но нужно использовать именно regexpr(
Неужели ничего не придумали? Перерыл кучу регулярных выражений с форумов, но с TRegExpr вылезают ошибки.
Единственное верное решение костыль, которое я сейчас вижу - обрабатывать текст и заменять запятые в кавычках на какие-либо еще символы, а потом обратно после обработки выражением
...
Рейтинг: 0 / 0
TRegExpr, csv
    #39740388
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
afordalekcvp,
спасибо, но нужно использовать именно regexpr(

А мы, вятские, робяты хватские: и часы могем, да топор не влазит (С)
...
Рейтинг: 0 / 0
TRegExpr, csv
    #39740416
Василий 2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
afordв csv бывают строки вида "sas (ыфыф, sasas,)" и парсер ломается
Вообще правильно он ломается, т.к. это неформат. Строки, содержащие сепаратор, должны закавычиваться.
...
Рейтинг: 0 / 0
TRegExpr, csv
    #39740499
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Василий 2afordв csv бывают строки вида "sas (ыфыф, sasas,)" и парсер ломается
Вообще правильно он ломается, т.к. это неформат. Строки, содержащие сепаратор, должны закавычиваться.
Суть в том, что он обрабатывает RegExp'ом. Замени скобки на кавычки - ничего не поменяется.
...
Рейтинг: 0 / 0
TRegExpr, csv
    #39740529
Василий 2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alekcvpСуть в том, что он обрабатывает RegExp'ом. Замени скобки на кавычки - ничего не поменяется.
Да нет. Если б был формат - можно как-то извращенски с регэскпом попробовать, хотя бы для частного случая (без экранирования кавычек). А сейчас даже КА не поможет (если, конечно, у него не собственный формат - но тогда это и не CSV). В последнем случае достаточно просто добавить группу "\(.*\)". Но опять же это сработает только для частного случая, и всегда можно будет найти вариант, который поломает этот RE
...
Рейтинг: 0 / 0
TRegExpr, csv
    #39740546
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Василий 2Но опять же это сработает только для частного случая, и всегда можно будет найти вариант, который поломает этот REИменно поэтому там нужен собственный парсер, т.к. regexp - это всё-таки немного про другое.
...
Рейтинг: 0 / 0
TRegExpr, csv
    #39740632
Гирлионайльдо
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Мне не жалко, держи [^(,]+(?:\([^)]+\)){0,2}[^),]*

Пример работы https://regex101.com/r/bF5wT0/4
...
Рейтинг: 0 / 0
TRegExpr, csv
    #39740633
Гирлионайльдо
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Там ещё много есть примеров с использованием рекурсии.

А данный партерн легко и такое распарсит

1997,Ford,E350,"ac, abs, moon",3000.00
1999,Chevy,"Venture «Extended Edition»","",4900.00
1996,Jeep,Grand Cherokee,"MUST SELL! air, moon roof, loaded",4799.00
...
Рейтинг: 0 / 0
TRegExpr, csv
    #39740660
aford
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Гирлионайльдо,
Спасибо!
...
Рейтинг: 0 / 0
TRegExpr, csv
    #39740662
aford
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Гирлионайльдо,
А если не поломанный csv?
Вот так не срабатывает автор[^",]+(?:\"[^"]+\"){0,2}[^",]*
...
Рейтинг: 0 / 0
TRegExpr, csv
    #39740663
zinpub
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ГирлионайльдоМне не жалко, держи [^(,]+(?:\([^)]+\)){0,2}[^),]*

Пример работы https://regex101.com/r/bF5wT0/4

Красиво! Но... если
...
Рейтинг: 0 / 0
TRegExpr, csv
    #39740701
Гирлионайльдо
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
aford,

Да. Забыл добавить перенос.


Если сломанный, то вот так

https://regex101.com/r/bF5wT0/5

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
value 1,sasasas (sasas,sasas sas,s s, (htrth) asasas,), value 3

value 4, value 5, value 6


1997,Ford,E350,"ac, abs, moon",3000.00
1999,Chevy,"Venture «Extended Edition»","",4900.00
1996,Jeep,Grand Cherokee,"MUST SELL! air, moon roof, loaded",4799.00 



Даёт такой ответ

matchgroupis_participatingstartendcontent 10yes018zend_mm_heap *heap 11yeszend_mm_heap *heap 20yes1944 void* (*_malloc)(size_t) 21yes void* (*_malloc)(size_t) 30yes4566void (*_free)(void*) 31yesvoid (*_free)(void*) 40yes67100" void* (*_realloc)(void* size_t)" 41yes" void* (*_realloc)(void* size_t)"
...
Рейтинг: 0 / 0
TRegExpr, csv
    #39740703
Гирлионайльдо
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
matchgroupis_participatingstartendcontent10yes07value 111no-1-112yes07value 120yes854"sasasas (sasassasas sass s (htrth) asasas)"21yes854"sasasas (sasassasas sass s (htrth) asasas)"30yes5563 value 331no-1-132yes5563 value 340yes6572value 441no-1-142yes6572value 450yes7381 value 551no-1-152yes7381 value 560yes8290 value 661no-1-162yes8290 value 670yes9397199771no-1-172yes9397199780yes98102Ford81no-1-182yes98102Ford90yes103107E35091no-1-192yes103107E350100yes108111"ac101no-1-1102yes108111"ac110yes112116 abs111no-1-1112yes112116 abs120yes117123 moon"121no-1-1122yes117123 moon"130yes1241313000.00131no-1-1132yes1241313000.00140yes1321361999141no-1-1142yes1321361999150yes137142Chevy151no-1-1152yes137142Chevy160yes143171"Venture «Extended Edition»"161no-1-1162yes143171"Venture «Extended Edition»"170yes172174""171no-1-1172yes172174""180yes1751824900.00181no-1-1182yes1751824900.00190yes1831871996191no-1-1192yes1831871996200yes188192Jeep201no-1-1202yes188192Jeep210yes193207Grand Cherokee211no-1-1212yes193207Grand Cherokee220yes208223"MUST SELL! air221no-1-1222yes208223"MUST SELL! air230yes224234 moon roof231no-1-1232yes224234 moon roof240yes235243 loaded"241no-1-1242yes235243 loaded"250yes2442524799.00 251no-1-1252yes2442524799.00
...
Рейтинг: 0 / 0
TRegExpr, csv
    #39740723
Василий 2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alekcvpИменно поэтому там нужен собственный парсер, т.к. regexp - это всё-таки немного про другое.
ТС-у нужен именно RE, он это осознанно подтвердил. Поэтому разговоры про то, что это не труЪ, что нужен парсер, и прочие КГ/АМ - бесполезны и оффтоп. Имхо
...
Рейтинг: 0 / 0
TRegExpr, csv
    #39740754
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Гирлионайльдоaford,

Да. Забыл добавить перенос.

Если сломанный, то вот так

https://regex101.com/r/bF5wT0/5

Продолжаем развлекаться :)
...
Рейтинг: 0 / 0
TRegExpr, csv
    #39740756
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Василий 2alekcvpИменно поэтому там нужен собственный парсер, т.к. regexp - это всё-таки немного про другое.
ТС-у нужен именно RE, он это осознанно подтвердил. Поэтому разговоры про то, что это не труЪ, что нужен парсер, и прочие КГ/АМ - бесполезны и оффтоп. Имхо
Ну да бесполезны. Клиент хочет выкопать котлован под дачный дом при помощи снегоуборочной машины, ничего не поделаешь, придётся копать :)
...
Рейтинг: 0 / 0
TRegExpr, csv
    #39740847
Гирлионайльдо
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alekcvp,

Врать не нужно.

Но скобки можно и убрать "/[^,]+\((?:[^()]{0,}|(?R))*\)|[^(,\n]+/g"
...
Рейтинг: 0 / 0
TRegExpr, csv
    #39741263
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Гирлионайльдоalekcvp,
Врать не нужно.

Где я вру? Я показал пример данных, на котором твой регекс не работает. Можешь гарантировать, что такого сочетания в исходных данных никогда не появится?..

...
Рейтинг: 0 / 0
21 сообщений из 21, страница 1 из 1
Форумы / Delphi [игнор отключен] [закрыт для гостей] / TRegExpr, csv
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]