shlex
— Простой лексический анализ¶
Исходный код: Lib/shlex.py
Класс shlex
позволяет легко писать лексические анализаторы для простых
синтаксисов, напоминающих синтаксис оболочки Unix. Это часто будет полезно для
написания мини-языков, (например, в файлах контроля для Python
приложений) или для парсинга закавыченных строк.
Модуль shlex
определяет следующие функции:
-
shlex.
split
(s, comments=False, posix=True)¶ Разделить строку s с помощью оболочечного синтаксиса. Если comments будет
False
(по умолчанию), то парсинг комментариев в данном строке будет отключена (настройкаcommenters
атрибутshlex
сущность к пустому строке). Эта функция работает в режиме POSIX по умолчанию, но использует режим, отличный от POSIX, если аргумент posix имеет значение false.
-
shlex.
join
(split_command)¶ Объединить маркеры списка split_command и возвращает строку. Эта функция является обратной к
split()
.>>> from shlex import join >>> print(join(['echo', '-n', 'Multiple words'])) echo -n 'Multiple words'
Возвращенный значение экранируется оболочкой, чтобы защитить от слабых мест инъекции (см.
quote()
).Добавлено в версии 3.8.
-
shlex.
quote
(s)¶ Возвращает оболочечная версия строки s. Возвращенный значение - строка, который может безопасно быть используемый как одним символом в командной строке оболочки для случаев, где вы не можете использовать список.
Эта идиома была бы небезопасна:
>>> filename = 'somefile; rm -rf ~' >>> command = 'ls -l {}'.format(filename) >>> print(command) # executed by a shell: boom! ls -l somefile; rm -rf ~
quote()
позволяет заглушить защитное отверстие:>>> from shlex import quote >>> command = 'ls -l {}'.format(quote(filename)) >>> print(command) ls -l 'somefile; rm -rf ~' >>> remote_command = 'ssh home {}'.format(quote(command)) >>> print(remote_command) ssh home 'ls -l '"'"'somefile; rm -rf ~'"'"''
Закавычивание совместимо с оболочками UNIX и с
split()
:>>> from shlex import split >>> remote_command = split(remote_command) >>> remote_command ['ssh', 'home', "ls -l 'somefile; rm -rf ~'"] >>> command = split(remote_command[-1]) >>> command ['ls', '-l', 'somefile; rm -rf ~']
Добавлено в версии 3.3.
Модуль shlex
определяет следующий класс:
-
class
shlex.
shlex
(instream=None, infile=None, posix=False, punctuation_chars=False)¶ Объект
shlex
сущность или подкласс сущности является объектом лексического анализатора. Аргумент инициализации, если он имеется, указывает, откуда следует читать символы. Это должен быть объект типа «файл/поток» с методами «read()
» и «readline()
» или «строка». Если аргумент не задан, входные данные будут взяты изsys.stdin
. Второй дополнительный аргумент - имя файла строка, который устанавливает начальный значениеinfile
атрибут. Если аргумент instream опущен или равенsys.stdin
, этот второй аргумент по умолчанию имеет значение stdin. Аргумент posix определяет режим работы: если posix не имеет значения true (по умолчанию), тоshlex
сущность будет работать в режиме совместимости. Работая в режиме POSIX,shlex
попытается быть максимально близким к правилам парсинг оболочки POSIX. Аргумент punctuation_chars предоставляет способ сделать поведение еще ближе к тому, как разбираются реальные оболочки. Это может занять ряд значения: по умолчанию значение,False
, сохраняет поведение, наблюдаемое под Python 3.5 и ранее. Если установлено значениеTrue
, то изменяется парсинг символов();<>|&
: любой прогон этих символов (считающихся символами пунктуации) возвращенный в качестве одного маркера. Если задано непустое строка символов, эти символы будут используемый в качестве знаков пунктуации. Все символы вwordchars
атрибут, которые отображаются в punctuation_chars, будут удалены изwordchars
. Дополнительные сведения см. в разделе Улучшенная совместимость с оболочками. punctuation_chars может быть установлен только при созданииshlex
сущность и не может быть изменен позже.Изменено в версии 3.6: Добавлен параметр punctuation_chars.
См.также
Модуль анализатор configparser
для конфигурационных файлов, подобных файлам
Windows .ini
.
Объекты shlex¶
У сущности shlex
есть следующие методы:
-
shlex.
get_token
()¶ Возвращает токен. Если токены были сложены в стопку с помощью функции
push_token()
, вытолкнуть токен из стека. В противном случае считывает один из входного потока. Если при чтении обнаруживается немедленное окончание файла,eof
является возвращенный (пустой строка (''
) в режиме, отличном от POSIX, иNone
в режиме POSIX).
-
shlex.
push_token
(str)¶ Поместить аргумент в стек токенов.
-
shlex.
read_token
()¶ Прочитать необработанный токен. Игнорировать отката (pushback) стека и не интерпретировать запросы источника. (Это обычно не является полезной точкой входа и документировано здесь только для полноты.)
-
shlex.
sourcehook
(filename)¶ Когда
shlex
обнаруживает исходный запрос (см.source
ниже), этому методу дают следующий символ как аргумент и ожидают к возвращает кортеж, состоящий из имени файла и открытого подобного файлу объекта.Обычно этот метод сначала снимает любые кавычки с аргумента. Если результатом является абсолютное имя пути, или в действительности не было предыдущего запроса источника, или предыдущий источник был потоком (например,
sys.stdin
), результат остается один. В противном случае, если результатом является относительное имя пути, перед именем файла в исходном стеке включения добавляется часть каталога (это поведение аналогично тому, как препроцессор C обрабатывает#include "file.h"
).Результат манипуляций рассматривают как имя файла и возвращенный как первый компонент кортежа, с
open()
, к которому обращаются это к yield второй компонент. (Примечание: это обратный порядок аргументов в инициализации сущность!)Этот хук выставлен так, чтобы вы могли использовать его, чтобы осуществить директивные пути поиска, добавление расширений файла и других хакерских проникновений пространства имен. Нет никакого соответствующего „завершения“, которое хук, но shlex сущность назовет методом
close()
поставленного входного потока когда это возвращает EOF.Для более четкого управления стекирования источников, используйте методы
push_source()
иpop_source()
.
-
shlex.
push_source
(newstream, newfile=None)¶ Поместить входной исходный поток во входной стек. Если указан аргумент имени файла, он будет доступен для использования в сообщениях об ошибках. Это - тот же метод используемый внутренне методом
sourcehook()
.
-
shlex.
pop_source
()¶ Выберать из стека входных данных последний выталкиваемый источник входных данных. Это - тот же метод используемый внутренне, когда lexer достигает EOF на сложенном входном потоке.
-
shlex.
error_leader
(infile=None, lineno=None)¶ Этот метод генерирует лидер сообщения об ошибке в формате метки ошибки компилятора Unix C. формат -
'"%s", line %d: '
, где%s
заменен названием текущего исходного файла, и%d
с текущим входным номером линии (дополнительные аргументы могут быть используемый, чтобы отвергнуть их).Это удобство обеспечено, чтобы поощрить пользователей
shlex
производить сообщения об ошибках в стандартном, parseable формате, понятом под Emacs и другими инструментами Unix.
У сущности shlex
подклассы есть некоторые переменные публичной
сущность, которые или управлять лексическим анализом или может быть
используемый для отладки:
-
shlex.
commenters
¶ Строка символов, которые признаются как начало комментариев. Все символы от начинающего комментария до конца строки игнорируются. Включает только
'#'
по умолчанию.
-
shlex.
wordchars
¶ Строка символов, которые будут накапливаться в мультистроковые токены. По умолчанию включает все алфавитно-цифровые символы ASCII и подчеркивание. В режиме POSIX также включаются акцентированные символы в наборе Latin-1. Если
punctuation_chars
не будет пуст, знаки, то~-./*?=
, который может появиться в технических требованиях имени файла и параметрах командной строки, будет также включен в этот атрибут, и любые знаки, которые появляются вpunctuation_chars
, будут удалены изwordchars
, если они будут присутствовать там. Еслиwhitespace_split
будет установлен вTrue
, то это не будет иметь никакого эффекта.
-
shlex.
whitespace
¶ Символы, которые будут считаться пробелами и пропущены. Пробелы ограничивают маркеры. По умолчанию включает пробел, таб, строку и возврат каретки.
-
shlex.
escape
¶ Символы, которые будут рассматриваться как экранирование. Это будет только используемый в режиме POSIX и включает просто
'\'
по умолчанию.
-
shlex.
quotes
¶ Знаки, которые будут считать кавычками строка. Токен накапливается до тех пор, пока снова не обнаружится одна и та же кавычка (таким образом, различные типы кавычек защищают друг друга, как в оболочке.) по умолчанию включает одинарные и двойные кавычки ASCII.
-
shlex.
escapedquotes
¶ Символы в
quotes
, которые будут интерпретировать escape-символы, определенные вescape
. Это - только используемый в режиме POSIX и включает просто'"'
по умолчанию.
-
shlex.
whitespace_split
¶ Если
True
, то маркеры будут разбиты только на пробелы. Это полезно, например, для командных строк парсинг сshlex
, получая символы похожим путем обстрелять аргументы. Когда используемый в сочетании сpunctuation_chars
, символы будут разделены на пробеле в дополнение к тем знакам.Изменено в версии 3.8:
punctuation_chars
атрибут был сделан совместимым сwhitespace_split
атрибут.
-
shlex.
infile
¶ Имя текущего входного файла, первоначально заданное во время создания экземпляра класса или сложенное по более поздним запросам источника. Это может быть полезно изучить при создании сообщений об ошибках.
-
shlex.
source
¶ Этот атрибут -
None
по умолчанию. Если вы назначите строка на него, это, то строка будет признан запросом включения лексического уровня, подобнымsource
ключевой в различных оболочках. То есть непосредственно следующий маркер будет открыт как имя файла, и вход будет взят из этого потока до EOF, и в этот момент будет вызван методclose()
этого потока, и входной источник снова станет исходным входным потоком. Исходные запросы могут складываться в любое количество уровней.
-
shlex.
debug
¶ Если этот атрибут будет числовым и
1
или больше, тоshlex
сущность напечатает многословную продукцию прогресса на своем поведении. Если вам нужно это использовать, вы можете прочитать источник модуля код, чтобы узнать подробности.
-
shlex.
lineno
¶ Номер исходной линии (количество отображаемых до сих пор новых линий плюс один).
-
shlex.
token
¶ Буфер маркеров. Возможно, было бы полезно изучить это при обнаружении исключений.
-
shlex.
eof
¶ Токен используемый для определения конца файла. Это будет установлено в пустой строка (
''
) в non-POSIX режиме, и кNone
в режиме POSIX.
-
shlex.
punctuation_chars
¶ Свойство, доступное только для чтения. Символы, которые будут считаться пунктуацией. Фрагменты знаков пунктуации будут возвращенный как один маркер. Однако обратите внимание, что проверка семантической достоверности не будет выполняться: например, «> > >» может быть возвращенный в качестве маркера, даже если он не может быть распознан как таковой оболочками.
Добавлено в версии 3.6.
Разбор правил¶
При работе в режиме, отличном от POSIX, shlex
будет пытаться соблюдать
следующие правила.
- Символы кавычек не распознаются в словах (
Do"Not"Separate
анализируется как единственное словоDo"Not"Separate
); - Символы escape не распознаются;
- Включение символов в кавычки сохраняет литерал значение всех символов в кавычках;
- Закрывающие кавычки - отдельные слова (
"Do"Separate
анализируется как"Do"
иSeparate
); - Если
whitespace_split
являетсяFalse
, любая символ, не объявленная как слово символ, пробел или кавычка, будет возвращенный как токен single-символ. Если оно равноTrue
,shlex
будет разделять слова только в пустых пространствах; - EOF сообщен с пустым строка (
''
); - Невозможно разобрать пустые строки, даже если их цитировать.
При работе в режиме POSIX shlex
попытается подчиниться следующим правилам
парсинг.
- Кавычки удаляются и не разделяют слова (
"Do"Not"Separate"
анализируется как единственное словоDoNotSeparate
); - Непроцитированные знаки экранирования (например,
'\'
) сохраняют литерал значение следующего символ, который следует; - Прилагающие знаки в кавычках, которые не являются частью
escapedquotes
(например,"'"
) сохраняют литерал значение всех знаков в кавычках; - Включение символов в кавычки, которые являются частью
escapedquotes
(например,'"'
), сохраняет литерал значение всех символов в кавычках, за исключением символов, упомянутых вescape
. Знаки экранирования сохраняют его специальное значение только, когда они сопровождаются цитатой в использовании или экранировании самого символа. Иначе символ экранирования будут считать нормальным символом. - EOF сигнализируется с помощью
None
значение; - В кавычках допускаются пустые строки (
''
).
Улучшенная совместимость с оболочками¶
Добавлено в версии 3.6.
Класс shlex
обеспечивает совместимость с парсинг, выполняемой общими
оболочками Unix, такими как bash
, dash
и sh
. Чтобы
воспользоваться этой совместимостью, укажите аргумент punctuation_chars
в конструкторе.
По умолчанию используется значение False
, которое сохраняет поведение до
3.6. Однако, если это установлено в True
, тогда парсинг знаков,
();<>|&
изменен: любой пробег этих знаков - возвращенный как единственный
символ. В то время как это нуждается в полном парсер для оболочек (который
был бы вне область видимости для стандартной библиотеки, учитывая разнообразие оболочек
там), это действительно позволяет вам выполнять обработку командных строк более
легко, чем вы могли иначе. Для иллюстрации можно увидеть разницу в следующем
фрагменте:
>>> import shlex
>>> text = "a && b; c && d || e; f >'abc'; (def \"ghi\")"
>>> s = shlex.shlex(text, posix=True)
>>> s.whitespace_split = True
>>> list(s)
['a', '&&', 'b;', 'c', '&&', 'd', '||', 'e;', 'f', '>abc;', '(def', 'ghi)']
>>> s = shlex.shlex(text, posix=True, punctuation_chars=True)
>>> s.whitespace_split = True
>>> list(s)
['a', '&&', 'b', ';', 'c', '&&', 'd', '||', 'e', ';', 'f', '>', 'abc', ';',
'(', 'def', 'ghi', ')']
Конечно, токены будут возвращенный, которые недействительны для оболочек, и вам потребуется реализовать собственные проверки ошибок токенов возвращенный.
Вместо передачи True
в качестве значение для параметра
punctuation_chars можно передать строка с определенными символами, которые
будут используемый, чтобы определить, какие символы составляют пунктуацию.
Например:
>>> import shlex
>>> s = shlex.shlex("a && b || c", punctuation_chars="|")
>>> list(s)
['a', '&', '&', 'b', '||', 'c']
Примечание
Когда punctuation_chars
определен, wordchars
атрибут увеличен со
знаками ~-./*?=
. Это объясняется тем, что эти символы могут отображаться в
именах файлов (включая подстановочные знаки) и аргументах командной строки
(например, --color=auto
). Следовательно:
>>> import shlex
>>> s = shlex.shlex('~/a && b-c --color=auto || d *.py?',
... punctuation_chars=True)
>>> list(s)
['~/a', '&&', 'b-c', '--color=auto', '||', 'd', '*.py?']
Однако для максимально близкого соответствия оболочке рекомендуется всегда
использовать posix
и whitespace_split
при использовании
punctuation_chars
, что полностью отрицает
wordchars
.
Для достижения наилучшего эффекта punctuation_chars
следует устанавливать в
сочетании с posix=True
. (Обратите внимание, что posix=False
- по умолчанию
для shlex
.)