![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
А напишите кто-нибудь табличку состояний CSV парсера? Т.е. последовательность символов, разделенных запятыми, в строках, разделенных \r или \r\n разбить на список списков строк. Если в строке должны быть служебные символы (т.е. запятая или \r \n) - строка обрамляется в кавычки, если внутри такой строки нужна кавычка - ставится две кавычки подряд.
На самом деле там немного сложнее, типа допустимо незначимые пробелы возле запятых, а значимыми их делают тоже через кавычки, управляющие символы <32 вроде тоже обязательно в кавычки, но это пофиг.
Вроде блин простая задачка, а каждый раз когда ее приходится делать - получаются на пару страниц конечные автоматы.
На самом деле там немного сложнее, типа допустимо незначимые пробелы возле запятых, а значимыми их делают тоже через кавычки, управляющие символы <32 вроде тоже обязательно в кавычки, но это пофиг.
Вроде блин простая задачка, а каждый раз когда ее приходится делать - получаются на пару страниц конечные автоматы.
no subject
Date: 2009-11-09 08:58 pm (UTC)Экспортирую из 2007 экселя в CSV. Он, зараза, и кавычки не ставит и служебные символы не эскейпит. С горя в XML начал экспортировать, а он угловые скобки html срезает.
Есть там кнопка "сделать чтоб работало" ?
no subject
Date: 2009-11-09 09:03 pm (UTC)no subject
Date: 2009-11-09 09:08 pm (UTC)Есть делиметер, допустим, запятая.
Поиск делиметера, по позициям - нарезка строки в список строк.
все, строка распаршена. Дальше по каждой подстроке уже убирание кавычек краевых, если они присутствуют, ну и байт стаффинг кавычек. Хотя на самом деле меня плющит, что вот делиметер внутри никаким байстаффингом не кодируется. То есть его просто тупо не может быть. Надо документ почитать про CSV, я не помню, как там по науке. Также и не помню как с \r\n быть по науке.
no subject
Date: 2009-11-09 09:12 pm (UTC)Поиск делимитера по позициям ломается на делимитерах внутри кавычек.
И обрабатываю я не одну строку а все строки подряд, потому что у меня может быть такое:
"test
test"
и это должно вернуться в виде одной строки внутри списка, с \r\n внутри
no subject
Date: 2009-11-09 09:44 pm (UTC)no subject
Date: 2009-11-09 09:47 pm (UTC)no subject
Date: 2009-11-09 09:49 pm (UTC)там кроме одного флага и значения предыдущего символа ничего не нужно
no subject
Date: 2009-11-09 09:55 pm (UTC)no subject
Date: 2009-11-09 09:59 pm (UTC)no subject
Date: 2009-11-09 10:03 pm (UTC)Вроде бы по стандарту, он должен игнорироваться, если около разделителей, а внутри строки недопустим.
no subject
Date: 2009-11-09 11:44 pm (UTC)Обработка пробелов - вообще не проблема.
no subject
Date: 2009-11-09 11:46 pm (UTC)no subject
Date: 2009-11-10 08:13 am (UTC)no subject
Date: 2009-11-09 09:47 pm (UTC)no subject
Date: 2009-11-09 09:58 pm (UTC)no subject
Date: 2009-11-09 10:02 pm (UTC)no subject
Date: 2009-11-09 10:05 pm (UTC)no subject
Date: 2009-11-09 10:10 pm (UTC)no subject
Date: 2009-11-09 10:19 pm (UTC)тогда для значения столбца и для текста целиком получаются следующие регулярные языки
V = (A\{',', 'eol', '"'})* + "(A\{'"'}+"")*"
S =((V,)*Veol)* = (V(, + eol))*
регулярный язык сводится к автомату. этот, если не ошибаюсь, к такому:
из умолчаний тут нельзя иметь кавычки как символы внутри значения не заключенного в кавычки, и после окончания кавычек должен идти разделитель значений. ну и плюс никакие колбеки нигде не вызываются, поэтому например неразличимы делимитеры.
no subject
Date: 2009-11-09 10:22 pm (UTC)Разделитель не всегда запятая. Иногда - точка с запятой. Зависит от настройки системы "разделитель элементов списка".
no subject
Date: 2009-11-09 10:26 pm (UTC)Хотя параметр "разделитель" для веб-сервиса отдающего csv, я тоже сделал, на случай "кто-нибудь захочет посмотреть из Excel с русской локалью"
no subject
Date: 2009-11-10 06:19 am (UTC)no subject
Date: 2009-11-10 07:13 am (UTC)no subject
Date: 2009-11-10 07:17 am (UTC)Как только ты сталкиваешься с ситуацией "быстро парсить поток байт" что льётся без остановки, спасают только автоматы (и то лишь в случае регулярных грамматик).
В остальных случаях нужны уже синтаксические анализаторы.
Рукописный лесосипед может требоваться в силу специфичности требований - таких как окружающий шум.
У меня при генерации мультиметодов нужно парсить содержимое комментариев. Но тут прикол в том, что парсеры эгоистичны - они парсят вход целиком.
Пришёл слабать автомат, что извлекает плюсовые комментарии из исходного кода.
Ничего сложного.
Автоматы простые как копейки, и умеют ээфективно парсить регулярные грамматики - в этом их сила.
Хоть, конечно, есть ньюансы применения, и конкретных реализацией автоматов чуть более, чем дохуя.
Но кодировать вручную иногда проще, чем искать хуй-пойми что.
no subject
Date: 2009-11-10 07:28 am (UTC)no subject
Date: 2009-11-10 07:30 am (UTC)Тогда состояния позволяют обрабатывать блок, сразу его пересылать дальше или писать на диск, и лишь затем аккумулировать следующий блок.
Или вообще построить конвейер из параллельного чтения данных по сети, обработке данных (парсингу) и записи блоков на диск.
Так что всё не так просто.
no subject
Date: 2009-11-10 07:35 am (UTC)Я ВЕРЮ!!!!!
Я прошу живой пример из жизни конкретно под CSV, плиз! Я мозгом скриплю - банально не могу представить где такое может произойти. Ну можалуйсто! :)
Про бинарные и т.п. потоковые протоколы - без вопросов.
no subject
Date: 2009-11-10 07:36 am (UTC)И это ещё нормально, у нас вон в csv гигабайтные блобы экспортили из SyBase =)
no subject
Date: 2009-11-10 07:39 am (UTC)no subject
Date: 2009-11-10 07:41 am (UTC)Кстати, это ничем и никем не запрещено - таскать толстые табличные данные в этом формате - универсально, просто, минимум накладных расходов (escaping запятой и перевода строки - мелочи).
no subject
Date: 2009-11-10 08:20 am (UTC)no subject
Date: 2009-11-10 08:27 am (UTC)no subject
Date: 2009-11-10 08:23 am (UTC)и последнее поле в строке по моему, не обработается корректно.
no subject
Date: 2009-11-10 08:26 am (UTC)