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