2012-09-26 16 views
5

ファイルパスを文字列として受け取り、解析し、コマンド名を追加し、リストを作成して実行するためにsubprocess.Popen()に渡すPythonスクリプトを作成しています。このスクリプトは、UnixとWindowsの両方のファイルパスを処理するもので、最終的には両方のシステムで実行する必要があります。Pythonでの特殊文字の自動エスケープを防ぐ方法

これをUnixで実行すると、誤ってエスケープ文字(たとえば\Users\Administrator\bin)が含まれているWindowsパスを指定すると、Pythonは埋め込みの\bをバックスペース文字として解釈します。私はそれが起こらないようにしたい。

私が知る限り、文字列変数を生の文字列として表す関数やメソッドはありません。 'r'修飾子は、文字列定数に対してのみ機能します。

はこれまでのところ、私が得ることができました最も近いがこれです:この時点で

winpath = "C:\Users\Administrator\bin" 
winpath = winpath.replace('\b','\\b') 
winpathlist = winpath.split('\\') 

、winpathlistは['C:','Users','Administrator','bin']、ない​​が含まれている必要があります。 \a\f\n\r\t\v - - ではなく\x

私は私が得るかもしれない他のエスケープを処理するためにwinpath.replace()に追加コールを追加することができます。

これを行うにはもっとpythonicな方法がありますか?

+5

どのように文字列に値を取得していますか? Pythonは\ bを文字列リテラルに入れない限りエスケープとして扱ってはいけません。あるいは、文字列の先頭にエスケープ文字として入ります。 (また、フォワードスラッシュは正常に機能します) – geoffspear

+0

@Wooble:今、doctest経由で入ってきます。 >>> myCommandObject。 ここで、myCommandObjectにはコマンド名(「ps」など)、パス、および引数のリストが含まれています。 スラッシュをバックスラッシュからスラッシュに変更することは選択できません。私の顧客は、これが彼が望んだものであることを明示した。 – poltr1

+0

私が言ったように、rは文字列リテラルでしか機能しません。文字列変数では機能しません。私は先導的なrをklugeとして見る。 とにかく、ここでdoctestの(またはその一部)があります: >>> myCommand.setExecutablePath( 'C:\プログラムファイル\ cygwinの\ cdrive \ binに') >>> myCommandList = myCommand.getLaunchList() >> > myCommandList ['C:\\\\プログラムファイル\\\\ cygwin \\\\ cdrive \\\\ bin \\\\ ps'、 '-e'、 '-f'] >>> myCommandList [0] .split( "\\\\") ['C:'、 'プログラムファイル'、 'cygwin'、 'cdrive'、 'bin'、 'ps'] 私はもはやエラーが発生しました。 – poltr1

答えて

6

winpathがハードコードされている場合は、文字列の前にrを使用して、"raw string"であることを示すことができます。 winpathをハードコードすることができない場合は

winpath = r"C:\Users\Administrator\bin" 

、あなたは、新しい文字列を作成しようとすることができます:ちょうどrepr(winpath)あり、かつrepr("\bin")があるとして、本当に、あなたを助けにはなりません

escaped_winpath = "%r" % winpath 

(... )

ソリューションは、最初から文字列を再構築することです:あなたはthat linkで関数の例を見つけることができますが、一般的な考え方は次のとおりです。

escape_dict={'\a':r'\a', 
      '\b':r'\b', 
      '\c':r'\c', 
      '\f':r'\f', 
      '\n':r'\n', 
      '\r':r'\r', 
      '\t':r'\t', 
      '\v':r'\v', 
      '\'':r'\'', 
      '\"':r'\"'} 

def raw(text): 
    """Returns a raw string representation of text""" 
    new_string='' 
    for char in text: 
     try: 
      new_string += escape_dict[char] 
     except KeyError: 
      new_string += char 
    return new_string 

、今、raw("\bin")はあなたに"\\bin"を与える(とない"\\x08in")...

+0

私はrepr()に慣れていません。それは2.6ですか?私はこの考えが好きで、将来必要な場合に備えてこれに掛かるでしょう。私の顧客の要請により、私はreplace()の呼び出しを取り出しました。代わりに、彼はdoctestからWindowsパステストを別のファイルに移動するように提案しました。提案していただきありがとうございます。 – poltr1

4

あなたは、文字列リテラルの表記

r"hello\nworld" 

にRを付加することで、生の文字列を作成することができますが

"hello\\nworld" 
なり

さらに読むことができますhere

+0

ネガティブ。私があなたが示唆するようにdoctest文字列にrを入れると、それは文字列の一部になります。 – poltr1

関連する問題