Python:打印/写入转义字符的意外行为

时间:2014-07-23 18:16:03

标签: python regex python-3.x

我试图读取可能包含\\\n\t字符串的文件,我想将其写为另一个文件{{ 1}},换行符和制表符。我对\的尝试似乎并不适用于我的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)\t反斜杠线。

我在翻译中玩了一下,看看我是否能找到解决方案,但一切都表现得像我(天真)期待的那样。

\n

至于实际写入文件,我有

使用open(os.path.join(target_path,name)," w")as out:         out.write(片断)

虽然我也尝试过使用$ 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}'

编辑:我已经查看了Python how to replace backslash with re.sub()How to write list of strings to file, adding newlines?等类似问题,但这些解决方案并不常用,我真的很喜欢这样做一个正则表达式,如果可能的话,因为它们似乎是比Python的标准字符串处理函数更强大的工具。

Edit2:不确定这是否有帮助,但我想我会尝试打印函数中的内容:

print(snippet, end="", file=out)

产量

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

编辑3:根据@ BrenBarn的建议将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}' 更改为snippet = re.sub(r"\\", "\\", snippet),并在源文件中添加测试字符串

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

所以我一定错过了一些明显的东西。这不是一个不需要许可来编程的好事。

Edit4:根据Process escape sequences in a string in Python,我将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)" 更改为:

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,但这远不止于此,这不是我想要的。以下是运行该功能后所看到的事情(\tprint显示的内容相同。我可能误以为write和{{1}不匹配,因为看起来我用来检查输出文件的编辑器如果进行了新的更改就不会更新。):

print

1 个答案:

答案 0 :(得分:2)

如果没有看到某些数据,很难判断这是否是您的主要问题,但有一个问题是您需要将第一次替换更改为:

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

原因是反斜杠在替换模式中也有意义(对于组反向引用),因此单个反斜杠不是有效的替换字符串。