如何在Python中获取字符串的原始表示?

时间:2012-12-08 14:48:06

标签: python python-3.x rawstring

我正在创建一个严重依赖正则表达式的类。

让我们说我的课看起来像这样:

class Example:
    def __init__(self, regex):
        self.regex = regex

    def __repr__(self):
        return 'Example({})'.format(repr(self.regex.pattern))

让我说我像这样使用它:

import re

example = Example(re.compile(r'\d+'))

如果我repr(example),我会'Example('\\\\d+')',但我想要'Example(r'\\d+')'。考虑到打印时的额外反斜杠,它显示正确。我想我可以实现它来返回"r'{}'".format(regex.pattern),但这并不适合我。万一Python软件基金会有一天会改变指定原始字符串文字的方式,我的代码就不会反映出来。不过,这是假设的。我主要担心的是这是否一直有效。不过,我无法想到一个优势的边缘情况。有没有更正式的方法呢?

编辑:似乎没有任何内容出现在Format Specification Mini-Languageprintf-style String Formatting guidestring module中。

1 个答案:

答案 0 :(得分:8)

rawstring表示的问题是,您不能以便携式(即不使用控制字符)的方式表示所有内容。例如,如果你的字符串中有换行符,则必须将字符串断开到下一行,因为它不能表示为rawstring。

那就是说,获取rawstring表示的实际方法就是你已经给出的:

"r'{}'".format(regex.pattern)

rawstrings的定义是没有应用任何规则,除非它们以它们开头的引号字符结束,并且您可以使用反斜杠转义所述引号字符。因此,例如,您不能在原始字符串表示中存储等同于"\"的字符串(r"\"会产生SyntaxError,r"\\"会产生"\\\\")。

如果你真的想这样做,你应该使用如下的包装器:

def rawstr(s):
    """
    Return the raw string representation (using r'') literals of the string
    *s* if it is available. If any invalid characters are encountered (or a
    string which cannot be represented as a rawstr), the default repr() result
    is returned.
    """
    if any(0 <= ord(ch) < 32 for ch in s):
        return repr(s)

    if (len(s) - len(s.rstrip("\\"))) % 2 == 1:
        return repr(s)

    pattern = "r'{0}'"
    if '"' in s:
        if "'" in s:
            return repr(s)
    elif "'" in s:
        pattern = 'r"{0}"'

    return pattern.format(s)

试验:

>>> test1 = "\\"
>>> test2 = "foobar \n"
>>> test3 = r"a \valid rawstring"
>>> test4 = "foo \\\\\\"
>>> test5 = r"foo \\"
>>> test6 = r"'"
>>> test7 = r'"'
>>> print(rawstr(test1))
'\\'
>>> print(rawstr(test2))
'foobar \n'
>>> print(rawstr(test3))
r'a \valid rawstring'
>>> print(rawstr(test4))
'foo \\\\\\'
>>> print(rawstr(test5))
r'foo \\'
>>> print(rawstr(test6))
r"'"
>>> print(rawstr(test7))
r'"'