簡體   English   中英

Python:打印/編寫轉義符的意外行為

[英]Python: unexpected behavior with printing/writing escape characters

我正在嘗試讀取一個文件,其中包含\\\\\\n\\t字符串,並且我想將這些字符串寫為\\ ,換行符和tab。 我對re.sub嘗試似乎未在我的.py文件中工作,但似乎在解釋器中工作。

這是我為實現此目的而編寫的功能:

def escape_parser(snippet):
    snippet = re.sub(r"\\", "\\", snippet)
    snippet = re.sub(r"\t", "\t", snippet)
    snippet = re.sub(r"\n", "\n", snippet)

    return snippet

這會導致sre_constants.error: bogus escape (end of line)包含反斜杠替換行時出現sre_constants.error: bogus escape (end of line) ,並且當我注釋掉反斜杠行時,似乎沒有用制表符或換行符替換文字字符串\\t\\n

我在解釋器中玩耍,看看是否可以找到解決方案,但是所有操作都符合我(天真)的期望。

$ python3
Python 3.4.0 (default, Mar 24 2014, 02:28:52) 
[GCC 4.2.1 Compatible Apple LLVM 5.1 (clang-503.0.38)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> test = "for(int ${1:i}; $1 < ${2:STOP}; ++$1)\n{\n\t$0\n}"
>>> import re
>>> test = "for(int ${1:i}; $1 < ${2:STOP}; ++$1)\n{\n\t$0\n}"
>>> print(re.sub(r"\n", "\n", test))
for(int ${1:i}; $1 < ${2:STOP}; ++$1)
{
    $0
}
>>> print(test)
for(int ${1:i}; $1 < ${2:STOP}; ++$1)
{
    $0
}
>>> test
'for(int ${1:i}; $1 < ${2:STOP}; ++$1)\n{\n\t$0\n}'
>>> t2 = re.sub(r"\n", "foo", test)
>>> t2
'for(int ${1:i}; $1 < ${2:STOP}; ++$1)foo{foo\t$0foo}'

至於實際寫入文件,我有

使用open(os.path.join(target_path,name),“ w”)為out:out.write(snippet)

盡管我也嘗試過使用print(snippet, end="", file=out)

編輯:我看過類似的問題,如Python如何用re.sub()替換反斜杠以及如何將字符串列表寫入文件,添加換行符? ,但是這些解決方案並不能很好地發揮作用,如果可能的話,我真的很想使用正則表達式來執行此操作,因為它們似乎比Python的標准字符串處理功能更強大。

Edit2:不確定這是否有幫助,但是我想我將嘗試打印該函數中發生的事情:

def escape_parser(snippet):                                                                                                                                                                                       
    print(snippet)                                                                                                                                                                                                
    print("{!r}".format(snippet))                                                                                                                                                                                 

    # snippet = re.sub(r"\\", "\\", snippet)                                                                                                                                                                      
    snippet = re.sub(r"\t", "\t", snippet)                                                                                                                                                                        
    snippet = re.sub(r"\n", "\n", snippet)                                                                                                                                                                        

    print(snippet)                                                                                                                                                                                                
    print("{!r}".format(snippet))                                                                                                                                                                                 

    return snippet

產量

for(int ${1:i}; $1 < ${2:STOP}; ++$1)\n{\n\t$0\n}
'for(int ${1:i}; $1 < ${2:STOP}; ++$1)\\n{\\n\\t$0\\n}'
for(int ${1:i}; $1 < ${2:STOP}; ++$1)\n{\n\t$0\n}
'for(int ${1:i}; $1 < ${2:STOP}; ++$1)\\n{\\n\\t$0\\n}'

Edit3:按照@BrenBarn的建議,將snippet = re.sub(r"\\\\", "\\\\", snippet)更改為snippet = re.sub(r"\\\\", r"\\\\", snippet)在我的源文件中添加測試字符串會產生

insert just one backslash: \\ (that's it)
"insert just one backslash: \\\\ (that's it)"
insert just one backslash: \\ (that's it)
"insert just one backslash: \\\\ (that's it)"

所以我一定錯過了一些明顯的事情。 不需要編程許可是件好事。

Edit4:按照Python中字符串中的Process轉義序列 ,我將escape_parser更改為:

def escape_parser(snippet):                                                                                                                                                                                                                                                                                                                                             
    print("pre-escaping: '{}'".format(snippet))                                                                                                                                                                   

    # snippet = re.sub(r"\\", r"\\", snippet)                                                                                                                                                                     
    # snippet = re.sub(r"\t", "\t", snippet)                                                                                                                                                                      
    # snippet = re.sub(r"\n", "\n", snippet)                                                                                                                                                                      
    snippet = bytes(snippet, "utf-8").decode("unicode_escape")                                                                                                                                                    

    print("post-escaping: '{}'".format(snippet))                                                                                                                                                                  

    return snippet

在某種意義上是可行的。 我最初的意圖是僅替換\\\\\\n\\t ,但這遠不止於此,這並不是我想要的。 這是通過該函數運行后的樣子(看起來, printwrite工作與此相同。我可能會誤認為printwrite不匹配,因為看起來好像我用來檢查輸出文件的編輯器不會如果進行了新更改,請進行更新。):

pre-escaping: 'for(int ${1:i}; $1 < ${2:STOP}; ++$1)\n{\n\t$0\n}'
post-escaping: 'for(int ${1:i}; $1 < ${2:STOP}; ++$1)
{
    $0
}'
pre-escaping: 'insert just one backslash: \\ (that's it)'
post-escaping: 'insert just one backslash: \ (that's it)'
pre-escaping: 'source has one backslash \ <- right there'
post-escaping: 'source has one backslash \ <- right there'
pre-escaping: 'what about a bell \a like that?'
post-escaping: 'what about a bell  like that?'

在不查看某些數據的情況下很難分辨這是否是您的主要問題,但是一個問題是您需要將第一個替換項更改為:

snippet = re.sub(r"\\", r"\\", snippet)

原因是反斜杠在替換模式中也具有含義(對於組反向引用),因此單個反斜杠不是有效的替換字符串。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM