2012-09-26 41 views
5

我正在寫一個Python腳本,它接受文件路徑作爲字符串,解析它們,追加一個命令名,並建立一個列表,然後傳遞給subprocess.Popen()執行。該腳本處理Unix和Windows文件路徑,最終應該在兩個系統上運行。如何防止在Python中自動轉義特殊字符

當我在Unix下運行這個版本時,如果我給Windows路徑無意中包含轉義字符(例如\Users\Administrator\bin),Python會將嵌入的\b解釋爲退格字符。我想防止這種情況發生。

據我所知,沒有函數或方法將字符串變量表示爲原始字符串。 'r'修飾符僅適用於字符串常量。

到目前爲止,我已經能夠獲得最接近的是這樣的:

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

在這一點上,winpathlist應該包含['C:','Users','Administrator','bin'],不​​。

,我可以添加額外調用winpath.replace()來處理其他逃脫我可能會 - \a\f\n\r\t\v - 但不是\x

有沒有更pythonic的方式來做到這一點?

+5

你如何獲得字符串的值? Python不應將\ b視爲轉義符,除非它處於字符串文字中,或者以字符串形式作爲轉義符開頭。 (另外,正斜槓工作得很好。) – geoffspear

+0

@Wooble:現在,它通過doctest進入。 >>> myCommandObject。setExcecutablePath('C:\ Program Files \ cygwin \ cdrive \ bin') 其中myCommandObject包含命令名稱(例如'ps'),路徑和參數列表。 將斜槓從反斜槓改爲正斜槓不是一種選擇;我的客戶明確表示這是他想要的。 – poltr1

+0

正如我所說,r只適用於字符串文字;它不適用於字符串變量。我把領先的r看成一個瘋子。 總之,這裏的文檔測試(或部分吧): >>> myCommand.setExecutablePath( 'C:\ Program Files文件\ cygwin的\ CDRIVE \ BIN') >>> myCommandList = myCommand.getLaunchList() >> > myCommandList ['C:\\\\ Program Files \\\ cygwin \\\\ cdr \\\\ bin \\\\ ps','-e','-f'] >>> myCommandList [0] .split(「\\\\」) ['C:','Program Files','cygwin','cdrive','bin','ps'] 我不再有任何錯誤,現在我添加了調用來替換。 – poltr1

回答

6

如果您的winpath是硬編碼的,您可能希望在字符串之前使用r以指示它是"raw string"

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

如果winpath不能硬編碼的,你可以嘗試創建一個新的字符串:

escaped_winpath = "%r" % winpath 

(這只是repr(winpath),並不會真正幫助你,因爲repr("\bin")是... )

一個解決辦法是重建從頭串:你可以在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()。相反,他建議我將Windows路徑測試從doctest中移出並放入單獨的文件中。感謝您的建議。 – poltr1

4

您可以通過預先R鍵字符串文字符號創建一個原始字符串

r"hello\nworld" 

成爲

"hello\\nworld" 

您可以閱讀更多here

+0

否定的。如果我按照您的建議在doctest字符串中輸入r,它就會成爲字符串的一部分。 – poltr1