在我意识到之前
shlex.split
,我做了如下:
import sys
_WORD_DIVIDERS = set((' ', '\t', '\r', '\n'))
_QUOTE_CHARS_DICT = {
'\\': '\\',
' ': ' ',
'"': '"',
'r': '\r',
'n': '\n',
't': '\t',
}
def _raise_type_error():
raise TypeError("Bytes must be decoded to Unicode first")
def parse_to_argv_gen(instring):
is_in_quotes = False
instring_iter = iter(instring)
join_string = instring[0:0]
c_list = []
c = ' '
while True:
# Skip whitespace
try:
while True:
if not isinstance(c, str) and sys.version_info[0] >= 3:
_raise_type_error()
if c not in _WORD_DIVIDERS:
break
c = next(instring_iter)
except StopIteration:
break
# Read word
try:
while True:
if not isinstance(c, str) and sys.version_info[0] >= 3:
_raise_type_error()
if not is_in_quotes and c in _WORD_DIVIDERS:
break
if c == '"':
is_in_quotes = not is_in_quotes
c = None
elif c == '\\':
c = next(instring_iter)
c = _QUOTE_CHARS_DICT.get(c)
if c is not None:
c_list.append(c)
c = next(instring_iter)
yield join_string.join(c_list)
c_list = []
except StopIteration:
yield join_string.join(c_list)
break
def parse_to_argv(instring):
return list(parse_to_argv_gen(instring))
这与python 2.x和3.x一起工作。在python 2.x上,它直接与字节字符串和unicode字符串一起工作。在python 3.x上,它
只有
接受[unicode]字符串,而不是
bytes
物体。
这与shell argv splitting_的行为不完全相同,它还允许引用cr、lf和tab字符作为
\r
,
\n
和
\t
,将它们转换为真正的CR、LF、TAB(
施莱克分裂
不这样做)。所以写我自己的函数对我的需要是有用的。我猜
施莱克分裂
如果只需要简单的外壳式argv拆分,则更好。我正在分享这段代码,以防它作为做一些稍微不同的事情的基线有用。