Рубрики
Без рубрики

Сколько способов вы можете сказать Newline? История о необычных новостях в CSV

Этот пост рассказывает вам о проблеме, которую мы обнаружили с количеством способов, которыми вы можете сказать «Newline», и быстрое прагматическое решение для смягчения этого в ваших CSV. Tagged с помощью Python, CSV, Unicode, кодирования.

Мы отлаживали проблему с дампом данных CSV клиента, когда мы столкнулись с проблемой. Этот дамп данных содержит библиографические метаданные, и те из вас, кто работает с библиографическими метаданными, узнают, что вы можете найти практически все: специальные персонажи, странная разметка, HTML, вы называете это. Этот пост рассказывает вам о проблеме, которую мы обнаружили с количеством способов, которыми вы можете сказать «Newline», и быстрое прагматическое решение для смягчения этого в ваших CSV.

Мы написали наши данные в CSV и теперь снова читали их. Как ни странно, некоторые линии были уродливыми – они были усечены частично без какой -либо очевидной причины.

Глядя на файл в Libreoffice, не помогло – это выглядело просто хорошо. Таким образом, мы подняли данные до одного из проблем с проблемой, и, глядя на них на нашей командной строке Python, мог бы увидеть возможного виновника:

u'Publications: \u2029A Case Report'

Расположенный в середине, есть \ u2029 персонаж Unicode, с которым вы вряд ли будете знакомы. Это персонаж для сепаратора абзаца, и не совсем безумно обнаружить, что в заголовке статьи (мы обнаружили около 10 на 100 000 названий в течение этого процесса). Вы даже можете увидеть, что это значит; Он предназначен для обеспечения макета для этого названия, поэтому выглядит так:

Publications:
A Case Study

Мы написали данные, используя писатель Python CSV так:

f = open(file, "wb", "utf-8")
writer = UnicodeWriter(f)
for article in articles:
    writer.writerow([article.id, article.title])

Здесь Unicodewriter является основной оберткой для писателя CSV, которая гарантирует, что вы правильно выписываете кодируемое.

Далее мы читаем данные как это:

f = open(file, "rb", "utf-8")
reader = UnicodeReader(f)
for row in reader:
    # do stuff

(UnicodeReader – это просто обратный UnicoDewriter выше, для получения подробной информации см. В той же ссылке).

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

Что ж, есть куча способов сказать «Newline». Если вы думали, что это было просто \ n или \ r \ n Ты ошибаешься. \ u2029 это способ сказать Newline. Так же \ u2028 Анкет Так же \ u0085 . На самом деле, есть достаточно способов, которыми мы догадались, что библиотека CSV, объединенная с Python, не знает их всех, и на самом деле это не так.

Читатель CSV заботится о новостях, но он полностью зависит от вашей операционной системы, чтобы справиться с ними. То есть он просто использует readline Чтобы получить следующую строку в вашем файле при его чтении. И ваша операционная система действительно понимает все варианты Newline, и она завершит линию и передаст ее обратно, как только она достигнет одного.

Читатель CSV достаточно умный, чтобы понять, что данные в ячейках могут законно содержать новички, он не просто предполагает, что мы заканчиваем каждый раз, когда чтение дает ему линию. Поскольку читатель является машиной состояния, он знает, есть ли мы в ячейке и содержит ли ячейка новая линия, она просто добавляет это к значению ячейки. Это делает это, ища разделитель в начале ячейки. Если кто -то существует, он не откажется от чтения новых линий, пока не достигнет заключительного разделителя. Если разделитель не существует, тем не менее, Newline – это то, что он ищет для прекращения ячейки и строки.

Так Если ваш CSV выглядит так:

cell 1,cell 2,"a cell\n
with newlines"

Ваш читатель CSV поймет, что это один ряд. Но Если это выглядит так:

cell 1,cell2,a cell\n
with newlines

Это будет интерпретировать это как два.

Наша настоящая проблема в том, что CSV писатель не обнаруживает эти новшество (это получит \ n , потому что это очевидно, но не другие), и по умолчанию это не цитирует содержимое ячейки, если только он не замечает особый символ. Он с радостью напишет ваш файл Newline в файле в файл в файле в некачественной строке, и ваш эквивалентный читатель не сможет прочитать строку обратно. То есть по умолчанию читатель Python CSV не является симметричным; Он не обязательно прочитать данные, которые написали!

Итак, этот CSV будет работать:

article_id,article_title
123456790,"This title has a\u2029 Paragraph separator"

Хотя это не будет:

article_id,article_title
123456790,This title has a\u2029 Paragraph separator

Как писатель CSV не признает \ u2029 Как новый символ, он не обертывает кавычки вокруг строки, как если бы он содержал \ n Анкет

Исправление, как только вы это узнаете, легко; При построении своего писателя в Python вы должны сделать это так:

writer = UnicodeWriter(f, quoting=csv.QUOTE_ALL)

Это гарантирует, что все ваши ячейки CSV цитируются, поэтому независимо от того, что там ни странно, вы не сломаете структуру файла. Как правило, это хорошая идея, даже если вы не используете Python.

Есть только пара нисходящих, которые могут иметь значение в зависимости от вашего контекста:

  • Это не поведение по умолчанию для писателя CSV, поэтому вы должны помнить, чтобы делать это каждый раз, когда вы думаете, что собираетесь иметь дело с такими грязными данными.

  • Это означает, что все цитируется, что добавляет ненужный размер к вашему файлу.

Когда мы столкнулись с этой проблемой, на каких -либо форумах мы не обсуждались на каких -либо форумах, так что, надеюсь, это поможет вам, если вы столкнетесь с той же проблемой.

Ричард – основатель в Коттеджские лаборатории , консультирование по разработке программного обеспечения, специализирующееся на всех аспектах жизненного цикла данных. Иногда он на щипцах в @richard_d_jones

Этот пост был первоначально опубликован Среда в июне 2018 года

Оригинал: “https://dev.to/richardjones/how-many-ways-can-you-say-newline-a-story-about-unusual-newlines-in-a-csv-2efc”