Экранированные последовательности

Для полноценного представления структуры текста или его специфики нам нужны какие-то особые символы. Некоторые символы должны управлять курсором (еще называют "кареткой" – отголосок из прошлого от печатных машинок). Еще нужны какие-то символы с помощью которы можно выполнять какие-нибудь служебные задачи, например, обозначать шестнадцатеричные или восьмеричные коды символов. Для таких целей и существуют экранированные последовательности.

Экранированные последовательности — это последовательности, которые начинаются с символа "\" за которым следует один или более символов.

Давайте сразу приведем пример:

>>> s = 'слово_1\nслово_2\nслово_3'
>>> 
>>> s    #  вывод строки "как есть"
'слово_1\nслово_2\nслово_3'
>>> 
>>> print(s)    #  вывод с помощью функции print()
слово_1
слово_2
слово_3

Обратите внимание на то как функция print() осуществила вывод – в тех местах, где были последовательности '\n' она выполнила переносы строк. Вы, конечно же, догадались, что '\n' – это экранированная последовательность. Единственное, что стоит добавить так это то, что такие последовательности воспринимаются интерпретатором как единственный символ, т.е. несмотря на то что последовательность может состоять из нескольких символов ей соответствует всего один-единственный код. Например:

>>> ord('\n')
10

Таблица последовательностей

Экранированных последовательностей не так уж много, так что давайте сначала перечислим их все в таблице, а потом подробно рассмотрим назначение каждой из них.

Последовательность Назначение
\newline Если после символа "\" сразу нажать клавишу Enter то это позволит продолжать запись с новой строки.
\\ Позволяет записать символ обратного слеша.
\' Позволяет записать один символ апострофа.
\" Позволяет записать один символ кавычки.
\a Гудок встроенного в систему динамика.
\b Backspace, он же возврат, он же "пробел назад" – удаляет один символ перед курсором.
\f Разрыв страницы.
\n Перенос строки (новая строка).
\r Возврат курсора в начало строки.
\t Горизонтальный отступ слева от начала строки (горизонтальная табуляция).
\v Вертикальный отступ сверху (вертикальная табуляция).
\xhh Шестнадцатеричный код символа (две шестнадцатеричные цифры hh).
\ooo Восьмеричный код символа (три восьмеричные цифры ooo).
\0 Символ Null.
\N{id} ID (идентификатор) символа в базе данных Юникода, или, проще говоря, его название в таблице Юникода.
\uhhhh Шестнадцатеричный код 16-битного символа Юникода (символ кодируемый двумя байтами).
\Uhhhhhhhh Шестнадцатеричный код 32-битного символа Юникода (символ кодируемый четырьмя байтами).
\other Под other понимается любая другая последовательность символов. Не является экранированной последовательностью (остается без изменений с сохранением в строке символа "\").

Примеры

\newline — новая строка

Данный символ позволяет записывать очень длинные "короткие" строки (строки в одинарных кавычках или апострофах) в несколько строк. Как это работает? Просто начните вводить строку, в необходимом месте введите символ "\" а потом сразу нажмите клавишу Enter и продолжайте ввод строки. Например:

>>> s = 'Это будет очень\
... , очень-очень\
... , ну прям оооооочень\
...  длинная строка'
>>> 
>>> s
'Это будет очень, очень-очень, ну прям оооооочень длинная строка'

Обратите внимание, что в результирующей строке вообще нет символа "\". И не забывайте что пробел тоже является символом, а последовательность \newline не является разделителем:

>>> s1 = 'a\
... b\
... c'
>>> 
>>> s1
'abc'
>>> 
>>> s2 = 'a\
...  b\
...  c'
>>> s2
'a b c'

\\ — обратный слеш

Позволяет указывать в строке необходимое количество обратных слешей, что может пригодиться при работе с файловой системой в Windows или работой с LATEX:

>>> s = 'D:\\\\мои документы\\книги\\Лутц.pdf'
>>> s
'D:\\\\мои документы\\книги\\Лутц.pdf'
>>> print(s)
D:\\мои документы\книги\Лутц.pdf
>>> 
>>> s = 'D:\\\\мои документы\\книги\\'
>>> s
'D:\\\\мои документы\\книги\\'
>>> print(s)
D:\\мои документы\книги\
>>> 
>>> s = '\\sum_{k=1}^{n}k^{2}={\\frac{n(n+1)(2n+1)}{6}}'
>>> s
'\\sum_{k=1}^{n}k^{2}={\\frac{n(n+1)(2n+1)}{6}}'
>>> 
>>> print(s)
\sum_{k=1}^{n}k^{2}={\frac{n(n+1)(2n+1)}{6}}

Обратите на то как выполняется непосредственный вывод строк, в котором сохраняются экранированные последовательности и на то как выполняется вывод с помощью функции print() которая выполняет их интерпретацию и заменяет последовательности \\ на \.

Новичков это немного сбивает с толку, так как они думают, что строка с путем D:\\\\мои документы\\книги\\ является неверной записью пути к директории, хотя это не так, потому что последовательность \\ интерпретируется как одино символ, которому ставится в соответствие один код, в чем легко убедиться:

>>> ord('\\')
92

\' — апостроф

Последовательность \' позволяет помещать внутрь строки необходимое количество апострофов:

>>> s = 'a\'b\'\'c\'\'\'d\'\'\'\'\''
>>> s
"a'b''c'''d'''''"

\" — кавычка

Так же как и \' позволяет помещать в строку необходимое количество кавычек:

>>> s = 'a\"b\"\"c\"\"\"d\"\"\"\"\"'
>>> s
'a"b""c"""d"""""'

\a — гудок динамика

Последовательность \a заставляет систему издать короткий звуковой гудок, который очень часто используется для предупреждения о чем-либо. Однако, услышите вы этот гудок или нет, как-то зависит от компьютера и операционной системы. Например я сейчас работаю на ноуте под Ubuntu и ничего не слышу, но на стационарном компьютере с Windows 7 все исправно работает. Использовать его или нет решайте сами, но в любом случае, этот символ никогда не выводится на экран:

>>> print('\abcd')
bcd

\b — backspace (пробел назад)

Если вы хоть раз нажимали клавишу Backspace на клавиатуре, то вы уже знаете предназначение этой последовательности – удалять один символ перед курсором:

>>> s = 'AAA\bBBB\bC'
>>> s
'AAA\x08BBB\x08C'
>>> print(s)
AABBC

Если \b находится в конце строки, то удаления не происходит:

>>> s = 'AAA\b'
>>> print(s)
AAA

Однако, в общем случае все зависит от того сколько символов \b следует подряд друг за другом и что следует за ними:

>>> print('AAAA\b\b\bC')
ACAA
>>> print('AAAA\b\b\bBBB\b\bC')
ABCB
>>> print('AAAA\b\b\bBBB\b\b\bCC')
ACCB
>>> print('AAAA\b\b\bBBB\b\b\bCCC')
ACCC

Данная последовательность используется крайне редко. Но если вы все еще не догадались как она работает, то лучше воспринимайте его не как удаление символов, а как перемещение курсора влево. Например, в строке 'AAAA\b\b\bC' мы как бы ничего и не удаляли, на самом деле три символа '\b\b\b' переместили курсор на три позиции влево, на на вторую букву 'A' и вместо нее напечатали символ 'C'.

Последовательность \b – это эхо из эры механических печатных машинок, у которых не было курсора, а была каретка, которую курсор и имитирует. Сейчас клавиша Backspace ассоциируется с удалением символа, но на самом деле, раньше выполнялось перемещение каретки на один символ влево, т.е. на одном и том же месте бумаги можно было напечатать несколько разных символов.


\f — разрыв страницы

Последовательность \f – указывает в каком месте заканчивается одна страница и начинается другая. Раньше он использовался для управления подачей бумаги в принтерах. Когда принтер встречал этот символ, это означало что ему надо было извлеч страницу и загрузить на печать следующий лист бумаги. Сейчас, он может встретиться (и то не факт, что встретится) разве что в исходных кодах некоторых языков программирования, в которых принято соглашение разбивать код на разделы с помощью этого символа. Например, интерпретатор Python способен учитывать \f при расчете отступов при анализе кода.

Данная последовательность переводит курсор на следующую строку и выполняет отступ, длина которого равна длине предшествоваишей \f части строки:

>>> s = 'aaa\fbbb\fccc\fddd'
>>> print(s)
aaa
   bbb
      ccc
         ddd
>>> 
>>> s = 'aaa\f\fbbb\f\fccc\f\fddd'
>>> print(s)
aaa

   bbb

      ccc

         ddd
>>> 
>>> s = 'aaaa\fbbb\fcc\fd'
>>> print(s)
aaaa
    bbb
       cc
         d

\n — перенос строки

Последовательность \n до банального проста – это просто перенос следующих за ним символов на следующую строку:

>>> s = 'a\nbb\nccc\ndddd'
>>> print(s)
a
bb
ccc
dddd

\r — возврат каретки

Последовательность \r возвращает курсор в начало строки, т.е. позволяет печатать одни символы "поверх" других. Например:

>>> s = 'aaaaaa\rbbb'
>>> print(s)
bbbaaa
>>> 
>>> s = 'aaaaaa\rbbb\rc'
>>> print(s)
cbbaaa

Данная последовательность позволяет зделать "полосу загрузки" или осуществлять вывод прогресса решения каких-нибудь задач. Но для этого нужно знать, что функция print() обладает параметром end который по умолчанию установлен в значение '\n', что заставляет заканчивать каждый вывод переводом на новую строку:

>>> print('aaa')    #  по умолчанию end = '\n'
aaa
>>> print('aaa', end = '\n')
aaa

Параметр end определяет каким символом должна заканчиваться строка, т.е. мы можем сами задать такой символ (или символы):

>>> for i in range(10):
...     print(i, end = '-->')
... 
0-->1-->2-->3-->4-->5-->6-->7-->8-->9-->

Если мы зделаем end = '\r', то мы сможем печатать строки "поверх" друг друга, но терминал делает это настолько быстро, что мы не успеем ничего заметить. Обычно, загрузка и выполнение каких-то задач сопровождается небольшими задержками, давайте, мы съимитируем такую задержку с помощью функции sleep() модуля time:

>>> import time    #  импортируем модуль
>>> 
>>> for i in range(20):
...     time.sleep(0.2)    #  делаем задержку в 200 милисекунд
...     print(str(i) + '%' + '|'*i, end = '\r')

\t — горизонтальная табуляция

Так же как и \n последовательность \t крайне проста – она просто делает один отступ (равносильно нажатию клавиши Tab):

>>> s = 'a\tbb\tccc'
>>> 
>>> print(s)
a	bb	ccc
>>> 
>>> 
>>> s = 'a\tb\t\tc\t\t\td'
>>> 
>>> print(s)
a	b		c			d

\v — вертикальная табуляция

Последовательность \v очень похожа на \f и точно так же родом из тех времен, когда принтером приходилось управлять чуть ли не на прямую. Вот только эта последовательность в отличии от \f, не заставляла его загружать новую страницу, а перемещала его вниз по странице на указанное количество строк.

>>> s = 'aaaa\vbbb\vcc\vd'
>>> print(s)
aaaa
    bbb
       cc
         d

Но самое любопытное, что от этих раритетов в некоторых областях даже не собираются отказываться - некоторые документы и стандарты до сих пор используют последовательности \v и \f.


\xhh — шестнадцатеричный код символа

Последовательность \xhh позволяет делать запись строк, используя шестнадцатеричный код символов:

>>> for i in 'word':
...     print(i, ' --> ', ord(i), ' --> ', hex(ord(i)))
... 
w  -->  119  -->  0x77
o  -->  111  -->  0x6f
r  -->  114  -->  0x72
d  -->  100  -->  0x64
>>> 
>>> 
>>> s = '\x77\x6f\x72\x6c\x64'
>>> s
'world'
>>> 
>>> print(s)
world

\ooo — восьмеричный код символа

Последовательность \ooo позволяет делать запись строк, используя восьмеричный код символов:

>>> for i in 'word':
...     print(i, ' --> ', ord(i), ' --> ', oct(ord(i)))
... 
w  -->  119  -->  0o167
o  -->  111  -->  0o157
r  -->  114  -->  0o162
d  -->  100  -->  0o144
>>> 
>>> 
>>> s = '\167\157\162\154\144'
>>> s
'world'
>>> 
>>> print(s)
world

\0 — Null

Данная последовательность ведет себя так, словно ее нет. В старые-добрые времена механических принтеров, эта последовательность обозначала простой, т.е. ничего не делать. Сейчас ее можно до сих пор встретить в языке C, в конце символьных строк, причем далее за "\0" другие цифры следовать не должны, иначе они будут восприниматься как другая экранированная восьмеричная последовательность. Ну а Python этот символ вообще никак не выводит:

>>> s = 'aaa\0bbbbb'
>>> s            #  наблюдаем его в непосредственном выводе
'aaa\x00bbbbb'
>>> print(s)     #  но print() не выводит
aaabbbbb

Тем не менее этот символ в строке сохраняется и влияет на ее длину.


\N{id} — идентификатор символа Юникода

Позволяет вводить символы в строку используя их название:

>>> s = '\N{Copyright Sign}'
>>> s
'©'
>>> 
>>> s = '\N{Winking Face}   \N{Flushed Face}'
>>> s
'😉   😳'

\uhhhh — 16-битный символ Юникода

Позволяет вводить символы в строку используя их двухбайтовый шестнадцатеричный код, причем данный способ позволяет вводить только двухбайтовые символы юникода (UTF-16BE):

>>> '\u2126'
'Ω'
>>> '\u0026'
'&'

\Uhhhhhhhh — 32-битный символ Юникода

Позволяет вводить символы в строку используя их четырехбайтовый шестнадцатеричный код, причем данный способ позволяет вводить только четырехбайтовые символы юникода (UTF-32BE):

>>> u'\U0001F633'
'😳'

\other — не экранированная последовательность

Если за символом "\" следует что-то другое, не перечисленное в данном списке, то это не считается экранированной последовательностью, а обычной строкой в которой на ряду с остальными символами присутствует и символ "\":

>>> s = 'aaaa\cccc'
>>> s
'aaaa\\cccc'
>>> 
>>> print(s)
aaaa\cccc

Но внимательность все же не помешает:

>>> s = 'aaaa\bbbb'    #  вроде экранированной последовательности нет
>>> s                  #  а она на самом деле есть - '\b'
'aaaa\x08bbb'
>>> 
>>> print(s)
aaabbb

Всегда экранируйте символ "\" последовательностью "\\" или используйте литерал неформатированных строк r'aaaa\bbbb'.