23.2. shlex —简单的词法分析
版本 1.5.2 中的新Function。
源代码: Lib/shlex.py
shlex类使您可以轻松地为类似于 Unix Shell 的简单语法编写词法分析器。这对于编写迷你语言(例如,在 Python 应用程序的运行控制文件中)或解析带引号的字符串通常很有用。
在 Python 2.7.3 之前,此模块不支持 UnicodeImporting。
shlex模块定义以下Function:
shlex.
split
(* s * [,Comment [,* posix *]])- 使用类似 shell 的语法分割字符串* s 。如果 comments 为False(默认值),则将禁用对给定字符串中的 Comments 的解析(将shlex实例的commenters属性设置为空字符串)。默认情况下,此函数在 POSIX 模式下运行,但如果 posix *参数为 false,则使用非 POSIX 模式。
2.3 版的新Function。
在 2.6 版中进行了更改:添加了* posix *参数。
shlex模块定义以下类:
-
- class *
shlex.
shlex
([* instream * [,* infile * [,* posix *]]])
- shlex实例或子类实例是词法分析器对象。初始化参数(如果存在)指定从何处读取字符。它必须是具有read()和readline()方法的类似于文件/流的对象,或者是字符串(从 Python 2.3 开始接受字符串)。如果未提供任何参数,则 Importing 将取自
sys.stdin
。第二个可选参数是文件名字符串,它设置infile属性的初始值。如果* instream *参数Ellipsis或等于sys.stdin
,则第二个参数默认为“ stdin”。 * posix 参数是 Python 2.3 中引入的,它定义了操作模式。如果 posix *不为真(默认值),则shlex实例将在兼容模式下运行。在 POSIX 模式下运行时,shlex将try尽可能接近 POSIX Shell 解析规则。
- class *
See also
-
Module ConfigParser
-
解析器,用于类似于 Windows
.ini
文件的配置文件。
23.2.1. shlex 对象
shlex实例具有以下方法:
-
shlex.
get_token
( )- 返回令牌。如果令牌已使用push_token()进行堆叠,请从堆叠中弹出令牌。否则,请从 Importing 流中读取一个。如果读取遇到文件的立即结束,则返回eof(在非 POSIX 模式下为空字符串(
''
,在 POSIX 模式下为None
)。
- 返回令牌。如果令牌已使用push_token()进行堆叠,请从堆叠中弹出令牌。否则,请从 Importing 流中读取一个。如果读取遇到文件的立即结束,则返回eof(在非 POSIX 模式下为空字符串(
-
shlex.
push_token
(* str *)- 将参数压入令牌堆栈。
-
shlex.
read_token
( )- 读取原始令牌。忽略推回堆栈,并且不解释源请求。 (这通常不是有用的切入点,此处仅出于完整性目的在此处进行了说明.)
-
shlex.
sourcehook
(* filename *)
通常,此方法首先会删除参数中的所有引号。如果结果是绝对路径名,或者没有有效的先前的源请求,或者先前的源是流(例如sys.stdin
),则结果将保留。否则,如果结果是相对路径名,则在源包含堆栈上紧接在文件名之前的文件名的目录部分会被加上前缀(此行为类似于 C 预处理器处理#include "file.h"
的方式)。
操纵的结果被视为文件名,并返回为 Tuples 的第一个组件,并在其上调用open()以产生第二个组件。 (注意:这与实例初始化中的参数 Sequences 相反!)
该钩子是公开的,因此您可以使用它来实现目录搜索路径,添加文件 extensions 和其他名称空间黑客。没有相应的“关闭”钩子,但是 shlex 实例在返回 EOF 时将调用源 Importing 流的close()方法。
若要更明确地控制源堆栈,请使用push_source()和pop_source()方法。
shlex.
push_source
(* stream * [,* filename *])- 将 Importing 源流推入 Importing 堆栈。如果指定了 filename 参数,则以后可在错误消息中使用它。这与sourcehook()方法内部使用的方法相同。
2.1 版中的新Function。
shlex.
pop_source
( )- 从 Importing 堆栈中弹出最后按下的 Importing 源。当词法分析器在堆叠的 Importing 流上达到 EOF 时,这是内部使用的相同方法。
2.1 版中的新Function。
shlex.
error_leader
([* file * [,* line *]])- 此方法以 Unix C 编译器错误标签的格式生成错误消息引导符;格式为
'"%s", line %d: '
,其中%s
替换为当前源文件的名称,%d
替换为当前 Importing 的行号(可使用可选参数覆盖它们)。
- 此方法以 Unix C 编译器错误标签的格式生成错误消息引导符;格式为
提供此便利是为了鼓励shlex用户以 Emacs 和其他 Unix 工具理解的标准可分析格式生成错误消息。
shlex子类的实例具有一些公共实例变量,这些变量可以控制词法分析或可用于调试:
-
shlex.
commenters
- 被视为 CommentsStarters 的字符串。从 CommentsStarters 到行尾的所有字符都将被忽略。默认情况下仅包含
'#'
。
- 被视为 CommentsStarters 的字符串。从 CommentsStarters 到行尾的所有字符都将被忽略。默认情况下仅包含
-
shlex.
wordchars
- 将累积为多字符标记的字符串。默认情况下,包括所有 ASCII 字母数字和下划线。
-
shlex.
whitespace
- 将被视为空格并被跳过的字符。空格限制标记。默认情况下,包括空格,制表符,换行符和回车符。
-
shlex.
escape
- 将被视为转义符的字符。仅在 POSIX 模式下使用,默认情况下仅包含
'\'
。
- 将被视为转义符的字符。仅在 POSIX 模式下使用,默认情况下仅包含
2.3 版的新Function。
-
shlex.
quotes
- 将被视为字符串引号的字符。令牌会累积,直到再次遇到相同的引号为止(因此,不同的引号类型会像在 shell 中一样相互保护.)默认情况下,包括 ASCII 单引号和双引号。
-
shlex.
escapedquotes
2.3 版的新Function。
shlex.
whitespace_split
- 如果
True
,令牌将仅在空格中分割。例如,这对于使用shlex解析命令行,以类似于 shell 参数的方式获取令牌很有用。
- 如果
2.3 版的新Function。
-
shlex.
infile
- 当前 Importing 文件的名称,最初是在类实例化时设置的,或者由以后的源请求堆叠在一起的。在构造错误消息时检查这一点可能很有用。
-
shlex.
instream
- shlex实例正在从中读取字符的 Importing 流。
-
shlex.
source
- 此属性默认为
None
。如果为它分配一个字符串,则该字符串将被识别为词法级包含请求,类似于各种 shell 中的source
关键字。也就是说,紧随其后的标记将作为文件名打开,并且将从该流中获取 Importing,直到 EOF,此时将调用该流的close()方法,并且 Importing 源将再次成为原始 Importing 流。源请求可以堆叠任何数量的深度。
- 此属性默认为
-
shlex.
debug
- 如果此属性为数字且
1
或更大,则shlex实例将在其行为上输出详细的进度输出。如果需要使用它,可以阅读模块源代码以了解详细信息。
- 如果此属性为数字且
-
shlex.
lineno
- 源行号(到目前为止已看到的换行数加一)。
-
shlex.
token
- 令牌缓冲区。在捕获异常时对此进行检查可能很有用。
-
shlex.
eof
- 用于确定文件结尾的令牌。在非 POSIX 模式下,它将被设置为空字符串(
''
),在 POSIX 模式下将被设置为None
。
- 用于确定文件结尾的令牌。在非 POSIX 模式下,它将被设置为空字符串(
2.3 版的新Function。
23.2.2. 解析规则
在非 POSIX 模式下运行时,shlex将try遵守以下规则。
-
单词内不能识别引号字符(
Do"Not"Separate
被解析为单个单词Do"Not"Separate
); -
无法识别转义字符;
-
用引号引起来的字符保留引号内所有字符的字面值;
-
用引号引起来的单词分开(
"Do"Separate
被解析为"Do"
和Separate
); -
如果whitespace_split为
False
,则任何未语句为单词字符,空格或引号的字符都将作为单字符标记返回。如果是True
,shlex只会在空白处分割单词; -
EOF 用空字符串(
''
)发出 signal; -
即使引用,也无法解析空字符串。
在 POSIX 模式下运行时,shlex将try遵守以下解析规则。
-
引号被删除,并且不要分隔单词(
"Do"Not"Separate"
被解析为单个单词DoNotSeparate
); -
不带引号的转义字符(例如
'\'
)保留后面的下一个字符的 Literals 值; -
将不包含在escapedquotes(例如
"'"
)中的引号引起来的字符保留引号内所有字符的 Literals 值; -
用引号括起escapedquotes(例如
'"'
)的字符可以保留引号内所有字符的 Literals 值,但escape中提到的字符除外。只有在使用引号或转义字符本身时,转义字符才保留其特殊含义。否则,转义字符将被视为普通字符。 -
EOF 以None值表示;
-
允许带引号的空字符串(
''
);