TGStat
TGStat
Введите текст для поиска
Расширенный поиск каналов
  • flag Russian
    Язык сайта
    flag Russian flag English flag Uzbek
  • Вход на сайт
  • Каталог
    Каталог каналов и чатов Поиск каналов
    Добавить канал/чат
  • Рейтинги
    Рейтинг каналов Рейтинг чатов Рейтинг публикаций
    Рейтинги брендов и персон
  • Аналитика
  • Поиск по публикациям
  • Мониторинг Telegram
Хитрый Питон

2 Sep, 12:07

Открыть в Telegram Поделиться Пожаловаться

Казалось бы, что может быть проще, чем разбить текст на строки? Может быть, кто-то еще помнит про \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/
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 …

1.9k 0 6 4 43
Каталог
Каталог каналов и чатов Подборки каналов Поиск каналов Добавить канал/чат
Рейтинги
Рейтинг каналов Telegram Рейтинг чатов Telegram Рейтинг публикаций Рейтинги брендов и персон
API
API статистики API поиска публикаций API Callback
Наши каналы
@TGStat @TGStat_Chat @telepulse @TGStatAPI
Почитать
Академия TGStat Исследование Telegram 2019 Исследование Telegram 2021 Исследование Telegram 2023
Контакты
Справочный центр Поддержка Почта Вакансии
Всякая всячина
Пользовательское соглашение Политика конфиденциальности Публичная оферта
Наши боты
@TGStat_Bot @SearcheeBot @TGAlertsBot @tg_analytics_bot @TGStatChatBot