Python中,如何解析字符串看起来像sys.argv中
问题描述:
我想解析字符串是这样的:Python中,如何解析字符串看起来像sys.argv中
-o 1 --long "Some long string"
到这一点:
["-o", "1", "--long", 'Some long string']
或相似。
这是不同于getopt或optparse,其中开始与sys.argv解析的输入(就像我有上面的输出)。有没有一个标准的方法来做到这一点?基本上,这是“分裂”,同时保持引用的字符串在一起。
我迄今为止最好的功能:
import csv
def split_quote(string,quotechar='"'):
'''
>>> split_quote('--blah "Some argument" here')
['--blah', 'Some argument', 'here']
>>> split_quote("--blah 'Some argument' here", quotechar="'")
['--blah', 'Some argument', 'here']
'''
s = csv.StringIO(string)
C = csv.reader(s, delimiter=" ",quotechar=quotechar)
return list(C)[0]
答
我相信你想要的shlex模块。
>>> import shlex
>>> shlex.split('-o 1 --long "Some long string"')
['-o', '1', '--long', 'Some long string']
答
我意识到了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
对象。
这并不表现完全一样,外壳argv的分裂,这也让CR,LF和制表符的报价为\r
,\n
和\t
,将它们转换为真正的CR,LF,TAB(shlex.split
不会做那)。所以编写我自己的功能对我的需求很有用。我想shlex.split
更好,如果你只是想简单的壳式argv分裂。我将分享这些代码,以便它可以用来做一些稍微不同的事情。
我自己的真正健忘揭示:http://stackoverflow.com/questions/92533,有我使用shlex.split。显然我只是忘了它。 – 2009-05-25 23:23:03
如果你真正需要的是“处理选项”而不是“在命令行上解析字符串”,你可以考虑http://docs.python.org/2/library/argparse.html – 2013-07-31 12:08:47