How to split a string into command line arguments like the shell in python?

前端 未结 3 1394
情话喂你
情话喂你 2020-12-20 15:21

I have command line arguments in a string and I need to split it to feed to argparse.ArgumentParser.parse_args.

I see that the documentation uses

3条回答
  •  悲哀的现实
    2020-12-20 15:49

    You could use the split_arg_string helper function from the click package:

    import re
    
    def split_arg_string(string):
        """Given an argument string this attempts to split it into small parts."""
        rv = []
        for match in re.finditer(r"('([^'\\]*(?:\\.[^'\\]*)*)'"
                                 r'|"([^"\\]*(?:\\.[^"\\]*)*)"'
                                 r'|\S+)\s*', string, re.S):
            arg = match.group().strip()
            if arg[:1] == arg[-1:] and arg[:1] in '"\'':
                arg = arg[1:-1].encode('ascii', 'backslashreplace') \
                    .decode('unicode-escape')
            try:
                arg = type(string)(arg)
            except UnicodeError:
                pass
            rv.append(arg)
        return rv
    

    For example:

    >>> print split_arg_string('"this is a test" 1 2 "1 \\" 2"')
    ['this is a test', '1', '2', '1 " 2']
    

    The click package is starting to dominate for command-arguments parsing, but I don't think it supports parsing arguments from string (only from argv). The helper function above is used only for bash completion.

    Edit: I can nothing but recommend to use the shlex.split() as suggested in the answer by @ShadowRanger. The only reason I'm not deleting this answer is because it provides a little bit faster splitting then the full-blown pure-python tokenizer used in shlex (around 3.5x faster for the example above, 5.9us vs 20.5us). However, this shouldn't be a reason to prefer it over shlex.

提交回复
热议问题