код перевода строки utf 8
Почему важно всегда ставить символ переноса строки в конце текстовых файлов?
Иногда при просмотре диффов коммитов через git log или git diff можно заметить следующий вывод:
Или на GitHub в интерфейсе для просмотра диффов:
Почему это так важно, что Git и GitHub предупреждают нас об этом? Давайте разберемся.
Что такое символ переноса строки?
Что может быть проще, чем текстовый файл? Просто текстовые данные — как хранятся на диске, так и отображаются. На самом деле правительство нам врёт всё немного сложнее.
Оффтопик про управляющие символы ASCII
Не все символы, которые содержатся в текстовых файлах, имеют визуальное представление. Такие символы ещё называют «управляющими», и к ним относятся, например:
Многие эти символы пришли к нам из эпохи печатных машинок, поэтому у них такие странные названия. И действительно, в контексте печатной машинки или принтера такие операции, как перевод строки (сместить лист бумаги вверх так, чтобы печатающая головка попала на следующую строку), возврат каретки (переместить печатающую головку в крайнее левое положение) и возврат на один символ назад, обретают смысл. При помощи возврата на один символ назад создавались жирные символы (печатаешь символ, возвращаешься назад и печатаешь его ещё раз) и буквы с диакритическими знаками, такие как à или ã (печатаешь символ, возвращаешься назад и печатаешь апостроф или тильду). Но зачем печатной машинке бибикалка?
Сегодня многие из этих символов потеряли смысл, но некоторые до сих пор выполняют функцию, схожую с исходной.
Текстовые редакторы отображают текстовые файлы в некоем адаптированном виде, преобразуя непечатаемые символы, например, переносы строк и табуляции преобразуются в настоящие отдельные строки или выравнивающие отступы.
Для набора символа переноса строки достаточно нажать клавишу «Enter», но на разных платформах этот символ закодируется по-разному:
Как видите, Windows точнее всего эмулирует поведение печатной машинки.
Почему перенос строки в конце файла важен?
Согласно определению из стандарта POSIX, который тоже пришёл к нам из эпохи печатных машинок:
Строка — это последовательность из нуля или более символов, не являющихся символом новой строки, и терминирующего символа новой строки.
Почему важен этот стандарт? Возможен миллиард способов реализовать одно и то же, и только благодаря стандартам, таким как POSIX, мы имеем сейчас огромное количество качественного ПО, которое не конфликтует друг с другом.
Т.е. если вы не ставите символ переноса строки в конце строки, то формально по стандарту такая строка не является валидной. Множество утилит из Unix, которыми я пользуюсь каждый день, написано в согласии с этим стандартом, и они просто не могут правильно обрабатывать такие «сломанные» строки.
Давайте, например, через Python создадим такой файл со сломанными строками:
Упс! wc нашла только 2 строки!
Давайте создадим еще один файл:
И попробуем теперь склеить два созданных файла при помощи утилиты cat :
Название cat — это сокращение от «конкатенация», и никак не связано с котиками. А жаль.
И опять какой-то странный результат! В большинстве случаев это не то, чего вы бы ожидали, но вполне возможны ситуации, когда вам нужен именно такой результат. Именно поэтому утилита cat не может самостоятельно вставлять отсутствующие символы переноса строки, иначе это сделало бы её поведение неконсистентным.
Ещё доводы:
Настраиваем редактор
Самый простой способ перестать думать о пустых строках и начать жить — это настроить свой текстовый редактор или IDE на автоматическое добавление символа переноса строки в конец файлов:
Для других редакторов смотрите настройку здесь.
Заключение
Возможно, такая маленькая деталь, как перенос строки в конце файла и не кажется очень важной, а тема вообще кажется спорной, но боюсь, что у нас нет другого выбора, кроме как принять это правило за данность и просто выработать привычку (или настроить инструментарий) всегда ставить символ новой строки в любых текстовых файлах, даже если этого не требуется явно. Это считается распространённой хорошей практикой, и как минимум убережёт вас и ваших коллег от всяких неожиданных эффектов при работе с утилитами Unix.
В текстовом редакторе это выглядит как лишняя пустая строка в конце файла:
HOWTO по Юникоду¶
В этом HOWTO обсуждается поддержка Python спецификации Юникод для представления текстовых данных и объясняются различные проблемы, с которыми люди обычно сталкиваются при работе с Юникод.
Знакомство с Юникодом¶
Определения¶
Сегодняшние программы должны уметь обрабатывать самые разные символы. Приложения часто интернационализированы для отображения сообщений и вывода на различных языках, выбираемых пользователем; той же программе может потребоваться вывести сообщение об ошибке на английском, французском, японском, иврите или русском языках. Веб-контент может быть написан на любом из этих языков, а также может включать различные символы эмодзи. Строковый тип Python использует стандарт Юникод для представления символов, что позволяет программам Python работать со всеми этими различными возможными символами.
Юникод (https://www.unicode.org/) — это спецификация, которая направлена на перечисление каждого символа, используемого человеческими языками, и присвоение каждому символу его собственного уникального кода. Спецификации Юникод постоянно пересматриваются и обновляются, чтобы добавить новые языки и символы.
Символ — это наименьший возможный компонент текста. «A», «B», «C» и т. д. — разные символы. То же самое и «È» и «Í». Символы различаются в зависимости от языка или контекста, о которых вы говорите. Например, для «римской цифры один» есть символ «Ⅰ», который отделён от прописной буквы «I». Обычно они выглядят одинаково, но это два разных символа, которые имеют разные значения.
Стандарт Юникод описывает, как символы представлены кодовыми точками. Значение кодовой точки — это целое число в диапазоне от 0 до 0x10FFFF (около 1.1 миллиона значений, из которых на данный момент присвоено около 110 тысяч). В стандарте и в этом документе кодовая точка записывается с использованием обозначения U+265E для обозначения символа со значением 0x265e (9822 в десятичной системе).
Стандарт Юникод содержит множество таблиц, в которых перечислены символы и соответствующие им кодовые точки:
Строго говоря, эти определения подразумевают, что говорить «это символ U+265E » бессмысленно. U+265E — кодовая точка, которая представляет некоторый конкретный символ; в данном случае он представляет собой символ «ЧЕРНЫЙ ШАХМАТНЫЙ КОНЬ», «♞». В неформальном контексте об этом различии между кодовыми точками и символами иногда забывают.
Символ представлен на экране или на бумаге набором графических элементов, который называется глифом. Например, глиф для прописной буквы A представляет собой два диагональных штриха и горизонтальный штрих, хотя точные детали будут зависеть от используемого шрифта. Большинству кода Python не нужно беспокоиться о глифах; определение правильного глифа для отображения, как правило, является задачей инструментария графического интерфейса пользователя или средства визуализации шрифтов терминала.
Кодировки¶
Подводя итог предыдущему разделу: Юникод строка — это последовательность кодовых точек, которые представляют собой числа от 0 до 0x10FFFF (1 114 111 в десятичной системе). Эта последовательность кодовых точек должна быть представлена в памяти как набор кодовых единиц, а затем кодовые единицы отображаются в 8-битные байты. Правила перевода Юникод строки в последовательность байтов называются кодировкой символов или просто кодировкой.
Первая кодировка, о которой вы можете подумать, использует 32-битные целые числа в качестве кодовой единицы, а затем использует представление ЦП 32-битных целых чисел. В этом представлении строка «Python» может выглядеть так:
Это простое представление, но при его использовании возникает ряд проблем.
Поэтому эта кодировка используется не очень часто, и люди вместо этого выбирают другие кодировки, более эффективные и удобные, например UTF-8.
UTF-8 — одна из наиболее часто используемых кодировок, и Python часто по умолчанию использует её. UTF означает «Формат преобразования Юникода», а «8» означает, что при кодировании используются 8-битные значения. (Существуют также кодировки UTF-16 и UTF-32, но они используются реже, чем UTF-8.) UTF-8 использует следующие правила:
У UTF-8 есть несколько удобных свойств:
Ссылки¶
Сайт Консорциума Юникода содержит символьные таблицы, глоссарий и PDF-версии спецификации. Будьте готовы к трудному чтению. Хронология происхождения и развития Юникод также доступен на сайте.
На канале Computerphile Youtube Том Скотт кратко обсуждает историю Юникод и UTF-8 (9 минут 36 секунд).
Чтобы помочь понять стандарт, Юкка Корпела написал вводное руководство для чтения таблиц символов Юникод.
Другая хорошая вступительная статья написал Джоэл Спольски. Если это введение не прояснило вам ситуацию, вам следует попробовать прочитать альтернативную статью, прежде чем продолжить.
Часто полезны записи в википедии; см., например, записи для «кодировка символов» и UTF-8.
Поддержка Юникода в Python¶
Теперь, когда вы изучили основы Юникод, мы можем взглянуть на особенности Юникода в Python.
Строковый тип¶
Кодировка по умолчанию для исходного кода Python — UTF-8, поэтому вы можете просто включить символ Юникод в строковый литерал:
Примечание: Python 3 также разрешает использование символов Юникод в идентификаторах:
Если вы не можете ввести определенный символ в своём редакторе или по какой-то причине хотите сохранить исходный код только в формате ASCII, вы также можете использовать escape-последовательности в строковых литералах. (В зависимости от вашей системы вы можете увидеть фактический глиф с заглавными буквами вместо экранирующего символа u.):
Преобразование в байты¶
В следующем примере показаны разные результаты:
Литералы Юникода в исходном коде Python¶
В идеале вы хотели бы иметь возможность писать литералы в естественной кодировке вашего языка. Затем вы можете редактировать исходный код Python с помощью вашего любимого редактора, который будет естественным образом отображать символы с диакритическими знаками и использовать правильные символы во время выполнения.
Python по умолчанию поддерживает написание исходного кода в UTF-8, но вы можете использовать практически любую кодировку, если объявите используемую кодировку. Это делается путём включения специального комментария в первой или второй строке исходного файла:
Если вы не добавите такой комментарий, по умолчанию будет использоваться кодировка UTF-8, как уже упоминалось. См. также PEP 263 для получения дополнительной информации.
Свойства Юникода¶
Спецификация Юникод включает базу данных с информацией о кодовых точках. Для каждой определенной кодовой точки информация включает имя символа, его категорию, числовое значение, если применимо (для символов, представляющих числовые понятия, такие как римские цифры, дроби, такие как одна треть и четыре пятых и т. д.). Есть также свойства, связанные с отображением, например, как использовать кодовую точку в двунаправленном тексте.
Следующая программа отображает некоторую информацию о нескольких символах и печатает числовое значение одного конкретного символа:
При запуске печатает:
Сравнение строк¶
При запуске выводит:
Первым аргументом функции normalize() является строка, дающая желаемую форму нормализации, которая может быть одной из NFC, NFKC, NFD и NFKD.
Стандарт Юникод также определяет, как проводить сравнения без регистра:
(Почему NFD() вызывается дважды? Поскольку есть несколько символов, которые заставляют casefold() возвращать ненормализованную строку, поэтому результат необходимо снова нормализовать. См. обсуждение и пример в разделе 3.13 стандарта Юникод.)
Регулярные выражения Юникод¶
Строка в этом примере будет числом 57, записанное как тайскими, так и арабскими цифрами:
Ссылки¶
Есть несколько хороших альтернативных обсуждений поддержки Юникод в Python:
Чтение и запись данных Юникод¶
Как только вы написали код, который работает с данными Юникод, следующая проблема — ввод/вывод. Как включить строки Юникод в свою программу и как преобразовать Юникод в форму, подходящую для хранения или передачи?
Возможно, вам не потребуется ничего делать в зависимости от ваших источников ввода и назначения вывода; вы должны проверить, поддерживают ли библиотеки, используемые в вашем приложении, Юникод изначально. Например, синтаксические анализаторы XML часто возвращают данные Юникод. Многие реляционные базы данных также поддерживают столбцы со значениями Юникод и могут возвращать значения Юникод из запроса SQL.
Одной из проблем является многобайтовый характер кодировок; один символ Юникод может быть представлен несколькими байтами. Если вы хотите читать файл фрагментами произвольного размера (скажем, 1024 или 4096 байтов), вам необходимо написать код обработки ошибок, чтобы уловить случай, когда только часть байтов, кодирующих один символ Юникод, читается в конце кусока. Одним из решений может быть считывание всего файла в память, а затем выполнение декодирования, но это мешает вам работать с файлами очень большого размера; если вам нужно прочитать файл размером 2 ГиБ, вам потребуется 2 ГиБ ОЗУ. (Более того, поскольку, по крайней мере, на мгновение вам понадобятся как закодированная строка, так и её версия Юникод в памяти.)
Поэтому читать Юникод из файла очень просто:
Также можно открывать файлы в режиме обновления, позволяя читать и писать:
Юникод символ U+FEFF используется в качестве метки порядка байтов (BOM) и часто записывается как первый символ файла, чтобы помочь с автоматическим определением порядка байтов в файле. Некоторые кодировки, такие как UTF-16, ожидают, что спецификация будет присутствовать в начале файла; когда используется такая кодировка, спецификация будет автоматически записана как первый символ и будет автоматически отброшена при чтении файла. Существуют варианты этих кодировок, такие как «utf-16-le» и «utf-16-be» для кодировок с прямым порядком байтов и обратным порядком байтов, которые определяют один конкретный порядок байтов и не пропускают BOM.
В некоторых областях также принято использовать «BOM» в начале файлов в кодировке UTF-8; имя вводит в заблуждение, поскольку UTF-8 не зависит от порядка байтов. Отметка просто сообщает, что файл закодирован в UTF-8. Для чтения таких файлов используйте кодек «utf-8-sig», чтобы автоматически пропустить отметку, если она есть.
Имена файлов в Юникоде¶
Большинство широко используемых сегодня операционных систем поддерживают имена файлов, содержащие произвольные символы Юникод. Обычно это реализуется путём преобразования строки Юникод в некоторую кодировку, которая зависит от системы. Сегодня Python все больше и больше использует UTF-8: Python в MacOS использовал UTF-8 для нескольких версий, а Python 3.6 также перешёл на использование UTF-8 в Windows. В системах Unix кодировка файловой системы будет только в том случае, если вы установили переменные среды LANG или LC_CTYPE ; если нет, кодировка по умолчанию снова UTF-8.
Функция sys.getfilesystemencoding() возвращает кодировку для использования в вашей текущей системе, если вы хотите выполнить кодирование вручную, но нет особых причин для беспокойства. При открытии файла для чтения или записи вы обычно можете просто указать строку Юникод в качестве имени файла, и она будет автоматически преобразована в нужную для вас кодировку:
Функция os.listdir() возвращает имена файлов, что вызывает вопрос: должна ли она возвращать версию имен файлов в формате Юникод или должна возвращать байты, содержащие закодированные версии? os.listdir() может делать и то, и другое, в зависимости от того, предоставили ли вы путь к каталогу в байтах или в строке Юникод. Если вы передадите строку Юникод в качестве пути, имена файлов будут декодированы с использованием кодировки файловой системы, и будет возвращен список строк Юникод, а передача байтового пути вернёт имена файлов в байтах. Например, предполагая, что кодировка файловой системы по умолчанию — UTF-8, запустите следующую программу:
вернёт следующий результат:
Первый список содержит имена файлов в кодировке UTF-8, а второй список содержит версии Юникод.
Обратите внимание, что в большинстве случаев вы можете просто использовать Юникод с этими API. API байтов следует использовать только в системах, где могут присутствовать недекодируемые имена файлов; сейчас это в основном только системы Unix.
Советы по написанию программ с поддержкой Юникод¶
В этом разделе представлены некоторые предложения по написанию программного обеспечения, работающего с Юникод.
Самый важный совет:
При использовании данных, поступающих из веб-браузера или другого ненадежного источника, распространенным методом является проверка на недопустимые символы в строке перед использованием строки в сгенерированной командной строке или сохранением её в базе данных. Если вы делаете это, будьте осторожны и проверяйте декодированную строку, а не закодированные байтовые данные; некоторые кодировки могут иметь интересные свойства, например, не быть биективными или не быть полностью совместимыми с ASCII. Это особенно верно, если во входных данных также указана кодировка, поскольку злоумышленник может выбрать хитрый способ скрыть вредоносный текст в закодированном байтовом потоке.
Преобразование между кодировками файлов¶
Класс StreamRecoder может прозрачно преобразовывать между кодировками, принимая поток, который возвращает данные в кодировке №1, и ведёт себя как поток, возвращающий данные в кодировке №2.
Файлы в неизвестной кодировке¶
Что делать, если вам нужно внести изменения в файл, но вы не знаете его кодировку? Если вы знаете, что кодировка совместима с ASCII, и хотите проверить или изменить только части ASCII, вы можете открыть файл с помощью обработчика ошибок surrogateescape :
Обработчик ошибок surrogateescape декодирует любые байты, отличные от ASCII, как кодовые точки в специальном диапазоне от U+DC80 до U+DCFF. Затем эти кодовые точки снова превратятся в те же байты, когда обработчик ошибок surrogateescape используется для кодирования данных и их обратной записи.
Ссылки¶
Одна секция Освоение Ввода-Вывода Python 3, речь на PyCon 2010 Дэвидом Бизли, обсуждает текстовую обработку и обработку двоичных данных.
PDF слайды для презентации Марка-Андре Лембурга «написание Юникод-зависимых приложений на Python» обсуждают вопросы кодирования символ, а также как интернационализировать и локализовать приложение. Эти слайды покрывают Python 2.x только.
Благодарности¶
Первоначальный черновик этого документа был написан Эндрю Кучлингом. С тех пор он был переработан Александром Белопольским, Георгом Брандлом, Эндрю Кучлингом и Эцио Мелотти.
Благодарим следующих людей, которые отметили ошибки или предложили предложения по этой статье: Эрик Араужо, Николас Бастин, Ник Коглан, Мариус Гедминас, Кент Джонсон, Кен Круглер, Марк-Андре Лембург, Мартин фон Лёвис, Терри дж. Риди, Сергей Сторчака, Эрик Сан, Чад Уитакр, Грэм Уайдман.
Escape-последовательности и числовые нотации в PHP
Привет, Хабр. В преддверии старта онлайн-курса «PHP-разработчик» подготовили традиционный перевод материала. Предлагаем также посмотреть запись прошедшего демо-занятия «Экосистема PHP».
Многие современные языки программирования поддерживают различные способы использования различных символов, таких как обычные английские латинские буквы, числа, символы, эмодзи и различные специальные символы, такие как символ новой строки или символ табуляции.
PHP, наряду со многими другими языками программирования, поддерживает определенное количество escape-последовательностей для использования различных символов, которые не могут быть набраны с обычной клавиатуры, не могут быть представлены в текстовой форме (например, невидимые символы или различные управляющие символы) или иным образом не считываются. Эти символы используют escape-последовательности, которые распознает PHP.
Что касается чисел, PHP поддерживает стандартные десятичные числа, но также может использовать и другие нотиции, такие как двоичное, восьмеричное, шестнадцатеричное и даже научное (scientific) представление. Они могут сделать код более читаемым и понятным в зависимости от контекста.
Двойные кавычки и Heredoc
В PHP строка с двойными кавычками ( «string» ) или Heredoc (смотрите ниже) поддерживает escape-последовательности и интерполяцию переменных.
PHP будет пытаться интерполировать переменные, если строковый литерал находится внутри строки с двойными кавычками или Heredoc.
Альтернативно (и желательно) интерполируемые переменные могут быть выделены фигурными скобками, так они будут выглядеть более удобочитаемыми:
Строки в одинарных кавычках ( ‘string’ ) и синтаксис Nowdoc не интерполируют переменные:
Только строки в двойных кавычках и Heredoc поддерживают escape-символы.
Экранирование символов
Поскольку PHP интерпретирует и интерполирует специальные символы внутри строковых литералов в двойных кавычках и heredoc, знак обратной косой черты ( \ ) используется как «escape-символ».
Использование второго символа обратной косой черты предотвращает преобразование первого символа обратной косой черты в escape-символ.
Символы табуляции: \t и \v
Новые строки: \r и \n
\r («возврат каретки») и \n («перевод строки») являются символами новой строки.
Escape-символ: \e
Если приведенный выше фрагмент выполняется в терминале, который поддерживает управляющие последовательности ANSI, он интерпретирует его и изменяет текст:
Символ новой страницы: \f
Восьмеричные escape-последовательности символов ASCII
PHP поддерживает экранирование восьмеричного числа в его соответствующий ASCII символ.
Для символа P можно использовать восьмеричную escape-последовательность:
Любой базовый символ ASCII можно представить с помощью такой записи:
Любое значение в диапазоне от \0 до \377 будет интерпретироваться как восьмеричная escape-последовательность ASCII символа.
Обратите внимание, что числа для расширенных символов ASCII (от 128 до 255) несовместимы с UTF-8. PHP считает значение 128 (восьмеричное: 200 ; шестнадцатеричное: 80 ) недопустимым, поскольку оно не является допустимым значением UTF-8.
Хотя PHP принимает такие значения, они считаются недопустимыми символами в контексте UTF-8.
Шестнадцатеричные escape-последовательности символов ASCII
Кроме того, шестнадцатеричные символы не чувствительны к регистру (т.е. AF равно af и aF ).
Тот же «PHP.Watch» пример можно переписать с помощью шестнадцатеричных escape-последовательностей:
Escape-последовательности символов Unicode
PHP поддерживает использование любого Unicode символа с префиксом \u и шестнадцатеричным значением code point внутри фигурных скобок.
PHP выдаст ошибку парсера, если символ Unicode превышает значение 10FFFF :
Форму записи Unicode \u<> можно использовать качестве escape-последовательности для любого символа. Вот несколько примеров:
Символ
Code point (Dec)
Code point (Hex)
Escape-последовательность Unicode
Таблица символов Юникода
Популярные наборы символов
Юникод
Юникод (по-английски Unicode) — это стандарт кодирования символов. Проще говоря, это таблица соответствия текстовых знаков (цифр, букв, элементов пунктуации ) двоичным кодам. Компьютер понимает только последовательность нулей и единиц. Чтобы он знал, что именно должен отобразить на экране, необходимо присвоить каждому символу свой уникальный номер. В восьмидесятых, знаки кодировали одним байтом, то есть восемью битами (каждый бит это 0 или 1). Таким образом получалось, что одна таблица (она же кодировка или набор) может вместить только 256 знаков. Этого может не хватить даже для одного языка. Поэтому, появилось много разных кодировок, путаница с которыми часто приводила к тому, что на экране вместо читаемого текста появлялись какие-то странные кракозябры. Требовался единый стандарт, которым и стал Юникод. Самая используемая кодировка — UTF-8 (Unicode Transformation Format) для изображения символа задействует от 1 до 4 байт.
Символы
Символы в таблицах Юникода пронумерованы шестнадцатеричными числами. Например, кириллическая заглавная буква М обозначена U+041C. Это значит, что она стоит на пересечении строки 041 и столбца С. Её можно просто скопировать и потом вставить куда-либо. Чтобы не рыться в многокилометровом списке следует воспользоваться поиском. Зайдя на страницу символа, вы увидите его номер в Юникоде и способ начертания в разных шрифтах. В строку поиска можно вбить и сам знак, даже если вместо него отрисовывается квадратик, хотя бы для того, чтобы узнать, что это было. Ещё, на этом сайте есть специальные (и не специальные — случайные) наборы однотипных значков, собранные из разных разделов, для удобства их использования.
Стандарт Юникод — международный. Он включает знаки почти всех письменностей мира. В том числе и тех, которые уже не применяются. Египетские иероглифы, германские руны, письменность майя, клинопись и алфавиты древних государств. Представлены и обозначения мер и весов, нотных грамот, математических понятий.
Сам консорциум Юникода не изобретает новых символов. В таблицы добавляются те значки, которые находят своё применение в обществе. Например, знак рубля активно использовался в течении шести лет прежде чем был добавлен в Юникод. Пиктограммы эмодзи (смайлики) тоже сначала получили широкое применение в Япониии прежде чем были включены в кодировку. А вот товарные знаки, и логотипы компаний не добавляются принципиально. Даже такие распространённые как яблоко Apple или флаг Windows. На сегодняшний день, в версии 8.0 закодировано около 120 тысяч символов.
© Таблица символов Юникода, 2012–2021.
Юникод® — это зарегистрированная торговая марка консорциума Юникод в США и других странах. Этот сайт никак не связан с консорциумом Юникод. Официальный сайт Юникода располагается по адресу www.unicode.org.
Мы используем 🍪cookie, чтобы сделать сайт максимально удобным для вас. Подробнее