2017-07-06 10 views
1

文字列にコマンドライン引数があり、それを分割してargparse.ArgumentParser.parse_argsに送る必要があります。どのようにPythonでシェルのような文字列を分割するには?

the documentationは、string.split()を十分に使用しています。しかし、複雑な場合は、

--foo "spaces in brakets" --bar escaped\ spaces 

などの機能がありますか?pythonでこれを行う機能はありますか?

)Javaについても同様の質問がありました。here)。

+0

'argparse.ArgumentParser.parse_args'の正確な出力内容 –

+0

あなたが持っている特定の問題を示す完全なプログラムを表示する必要があります。 –

答えて

8

これは何ですかshlex.split was created forです。

+0

ニース!それはPython 2.3以来利用可能です。 – randomir

+0

'shlex.split'はエスケープされた引用符に問題がありますか?例えば ​​'--foo" bar \ "baz" ' – user1735003

+0

@ user1735003:はい、通常はこれを扱うシェルです(' shlex'は 'sh'シェルルールとほとんど同じルールに従います)。 shlex.split(r ' - foo "bar \" baz "')'は '' '--foo'、 ''を生成します。 shres.split(あるいは明示的なリスト)の代わりに 'str.split'を使うとき、' argaz'文書は[怠け者です](https://bugs.python.org/issue20598) ;彼らは簡潔にするつもりだったが、「shlex」知識を必要とする精神的な負荷がなかった。 – ShadowRanger

0

あなたはclickパッケージからsplit_arg_stringヘルパー関数を使用することができます:「clickパッケージは構文解析し、コマンドの引数を支配し始めているが、私はドン

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

:たとえば

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 

それは文字列からの引数の解析をサポートしていると思う(argvからのみ)。上記のヘルパー機能は、bash完了時にのみ使用されます。

を編集してください:shlex.split()を@ShadowRangerの回答として提案するだけで何もお勧めできません。私がこの回答を削除しないのは、少し速い分割を提供してから、shlexで使用されている本格的なpure-pythonトークナイザ(上記の例では約3.5倍、5.9usと20.5us)があるからです。しかし、これはshlexよりも好む理由ではありません。

関連する問題