如何在Python中从字符串变量创建原始字符串?

14

您可以按照以下方式从字符串创建原始字符串:

test_file=open(r'c:\Python27\test.txt','r')

如何从字符串变量中创建一个原始变量,例如:

path = 'c:\Python27\test.txt'

test_file=open(rpath,'r')

因为我有一个文件路径:

file_path = "C:\Users\b_zz\Desktop\my_file"

当我执行:

data_list = open(os.path.expandvars(file_path),"r").readlines()
我得到:
Traceback (most recent call last):
  File "<pyshell#32>", line 1, in <module>
    scheduled_data_list = open(os.path.expandvars(file_path),"r").readlines()
IOError: [Errno 22] invalid mode ('r') or filename: 'C:\\Users\x08_zz\\Desktop\\my_file'

为什么你的错误信息中“b_zz”被替换成了“x08_zz”? - venpa
2
我想知道的是这个。 - alwbtc
2
´ord('\b')´ 是 8。要么加倍反斜杠,要么在代码中的字符串前面添加一个 ´r´。 - Matthias
为什么不一开始就写成 r"C:\Users\b_zz\Desktop\my_file" 呢?或者更好的方式是 "C:/Users/b_zz/Desktop/my_file" - Karl Knechtel
3个回答

11

一旦字符串被创建,就不存在所谓的“原始字符串”。""r""指定字符串的方式仅存在于源代码中。

这意味着"\x01"将创建一个由一个字节0x01组成的字符串,但r"\x01"将创建一个由4个字节'0x5c','0x78','0x30','0x31'组成的字符串。 (假设我们在谈论Python 2,并忽略编码问题)。

您在评论中提到,您正在从用户那里获取字符串(无论是GUI还是控制台输入,在这里都可以工作)-在这种情况下,字符串字符转义将不会被处理,因此您无需对其进行任何操作。 您可以轻松检查它,例如使用以下方式(或Windows等价方式,我只熟悉*nix):

% cat > test <<EOF                                             
heredoc> \x41
heredoc> EOF
% < test python -c "import sys; print sys.stdin.read()"
\x41

7

我将字符串转换为原始字符串的解决方案(仅适用于以下序列:'\a',\b','\f','\n','\r','\t','\v'。所有转义序列的列表在这里):

def str_to_raw(s):
    raw_map = {8:r'\b', 7:r'\a', 12:r'\f', 10:r'\n', 13:r'\r', 9:r'\t', 11:r'\v'}
    return r''.join(i if ord(i) > 32 else raw_map.get(ord(i), i) for i in s)

示例:

>>> file_path = "C:\Users\b_zz\Desktop\fy_file"
>>> file_path
'C:\\Users\x08_zz\\Desktop\x0cy_file'
>>> str_to_raw(file_path)
'C:\\Users\\b_zz\\Desktop\\fy_file'

但是我从GUI输入中获取路径字符串。如何在开头添加“r”? - alwbtc
1
用户所询问的是,如何将一个未知的字符串转换为“原始”字符串而不是解释字符串,以避免路径被二进制表示。 - Torxed
8
在内存中没有原始字符串。原始字符串只是源代码的辅助工具。如果你通过(GUI)输入获取字符串,一切都没问题。 - Matthias
1
@alwbtc 你如何从用户那里获取路径字符串?如果在其中得到了\b字符,我认为你没有得到想要的结果。 - Travis Griggs
1
您将会得到用户提供的确切内容。当您仅查看/使用一个值时,不会进行字符串转换/解码。"\b"部分与字符串本身无关,而是源代码解析的产物。 - viraptor
显示剩余8条评论

0

ndpu的解决方案对我很有效。

我忍不住想要改进它(使其与古老的Python 2版本兼容,并希望加速它):

_dRawMap = {8:r'\b', 7:r'\a', 12:r'\f', 10:r'\n', 13:r'\r', 9:r'\t', 11:r'\v'}

def getRawGotStr(s):
    #
    return r''.join( [ _dRawMap.get( ord(c), c ) for c in s ] )

我进行了仔细的时间试验,结果发现ndpu的原始代码稍微快一些。列表推导式很快,但生成器表达式更快。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接