0

我需要通过转义 Windows 路径分隔符来更改此字符串。我自己没有定义原始字符串,所以我不能预先添加原始字符串'r'。

我需要这个:

s = 'C:\foo\bar'

变成这样:

s = 'C:\\foo\\bar'

我在这里和其他地方能找到的所有东西都说要这样做:

s.replace( r'\\', r'\\\\' )

(为什么我必须在我无法想象的原始字符串中转义字符)

但是打印字符串会导致这种情况。显然有些东西决定重新解释修改后的字符串中的转义:

C:♀oar

这在 Perl 中会很简单。如何在 Python 中解决这个问题?

4

2 回答 2

4

来来回回问了一堆问题,实际问题是这样的:

您有一个文件,其内容如下:

C:\foo\bar
C:\spam\eggs

您想读取该文件的内容,并将其用作路径名,并且您想知道如何转义。

答案是你根本不需要做任何事情。

反斜杠序列在string literalsinput中处理,而不是在您从文件或从(在 3.x 中;在 2.x 中)等读取的字符串对象中处理raw_input。因此,您不需要转义这些反斜杠序列。

如果您考虑一下,您无需在字符串周围添加引号即可将其转换为字符串。这是完全相同的情况。引号和转义反斜杠都是字符串表示的一部分,而不是字符串本身。


换句话说,如果您将该示例文件保存为paths.txt,并运行以下代码:

with open('paths.txt') as f:
    file_paths = [line.strip() for line in f]
literal_paths = [r'C:\foo\bar', r'C:\spam\eggs']
print(file_paths == literal_paths)

…它会打印出来True


当然,如果您的文件生成不正确并且充满了这样的垃圾:

C:♀oar

那么就没有办法“逃避反斜杠”,因为它们不是用来逃避的。您可以尝试编写启发式代码来重建应该存在的原始数据,但这是您能做的最好的事情。

例如,您可以执行以下操作:

backslash_map = { '\a': r'\a', '\b': r'\b', '\f': r'\f', 
                  '\n': r'\n', '\r': r'\r', '\t': r'\t', '\v': r'\v' }
def reconstruct_broken_string(s):
    for key, value in backslash_map.items():
        s = s.replace(key, value)
    return s

但是,如果有任何十六进制、八进制或 Unicode 转义序列要撤消,这将无济于事。例如,'C:\foo\x02'两者'C:\foo\b'都表示完全相同的字符串,所以如果你得到那个字符串,就无法知道你应该转换到哪个字符串。这就是为什么你能做的最好的就是启发式。

于 2013-08-03T01:15:03.757 回答
0

不要做s.replace(anything)。只需r在字符串文字前面加上开头引号之前,就可以得到一个原始字符串。任何基于字符串替换的东西都将是一个可怕的组合,因为s它实际上并没有反斜杠;您的代码中有反斜杠,但这些不会成为实际字符串中的反斜杠。

如果字符串中实际上有反斜杠,并且您希望字符串在曾经有一个反斜杠的地方有两个反斜杠,那么您需要这样:

s = s.replace('\\', r'\\')

这将用两个反斜杠替换任何单个反斜杠。但是,如果字符串在源代码中按字面意思显示为s = 'C:\foo\bar',则唯一合理的解决方案是更改该行。它坏了,你对其余代码所做的任何事情都不会让它不坏。

于 2013-08-03T00:02:50.963 回答