TGViewer
Хитрый Питон Хитрый Питон @tricky_python · 3.45K subscribers
Post #265 1.76K
Казалось бы, что может быть проще, чем разбить текст на строки? Может быть, кто-то еще помнит про \n, \r и \r\n, и в старые времена надо было знать или угадывать, что используется в файле в зависимости от системы. Мы привыкли, что в python обычно все просто - splitlines()`/`split('\n') и готово, дальше под капотом работает магия. На самом деле все, конечно, гораздо сложнее 🙂 Джеймс Беннет написал отличный разбор, как все работает сейчас, почему и откуда это все взялось.

Началось все с ASCII и телетайпов: LF (`0x0A`) двигал бумагу вниз, CR (`0x0D`) возвращал каретку. Два символа нужны, потому что механике требуется время, чтобы каретка успела доехать. Потом терминалы стали виртуальными, необходимость отпала, и все разбежались кто куда: CP/M → DOS → Windows оставили CR LF, Multics → Unix взяли только LF, Apple и Commodore - только CR. В питон еще в версии 2.3 завезли PEP 278 - universal newlines.

Но так-то в ASCII есть еще FF (form feed, `0x0C`) и VT (vertical tab, `0x0B`) - они как бы не "новая строка", но по факту переводят вывод на другую строку. Плюс NEL (`0x85`), который завели для совместимости с IBM-овской кодировкой EBCDIC, где был свой символ для перевода строки.

Дальше Юникод добавил U+2028 LINE SEPARATOR и U+2029 PARAGRAPH SEPARATOR, потому что обычный newline стал двусмысленным: текстовые редакторы с автопереносом начали использовать его как разрыв абзаца, а не строки.

Самое неожиданное - последние три: U+001C, U+001D, U+001E, они же ASCII-шные FILE, GROUP и RECORD SEPARATOR, которыми когда-то разделяли записи в данных. К разрыву строк они отношения не имеют, а попали в список через алгоритм для текста со смешанным направлением письма (слева направо и справа налево). Если, например, в тексте на арабском вставка цитаты на английском, направление переключается спецсимволом, и действует он до конца абзаца. А у этих трех разделителей в свойствах как раз прописано "конец абзаца" - вот они и оказались в одном списке с настоящими переводами строк.

Сейчас это все собрано в splitlines(). А практический вывод простой: splitlines() и split('\n') - это не одно и то же. Если в данных попадется \x1c или \u2028 (а в выгрузках из всяких легаси-систем они попадаются), результат будет разный. Для парсинга структурированных форматов лучше явно указывать разделитель.

Оригинал https://www.b-list.org/weblog/2026/aug/10/newlines/
James Bennett Breaking up (lines) is hard to do Here’s a seemingly simple question: given a chunk of multi-line text, how do you split it and return an array …
  • 👍 32
  • 🔥 11
More from @tricky_python
  1. Sep 16, 2026Друзья, у нас важное объявление! Некоторые из вас помнят наши курсы Learn Python - когда-т…
  2. Sep 7, 2026В документации Python появилась отдельная страница со сложностью операций над встроенными…
  3. Sep 3, 2026В эту пятницу в 14:00 (по мск) обсудим новости августа в прямом эфире Moscow Python Podcas…
  4. Aug 31, 2026Пока я был в отпуске и путешествовал, вышел перевод документации Python на русский. Звучит…
  5. Aug 20, 2026Есть такой язык - Mojo: • синтаксически он близок к python • дает возможность вызывать и и…
  6. Aug 18, 2026Пару недель назад я писал про то, насколько больше security-отчетов теперь приходит для CP…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →