从常规字符串('')中告诉原始字符串(r'')?

时间:2011-05-06 19:09:12

标签: python regex string

我目前正在构建一个必须根据模式匹配文件名的工具。为方便起见,我打算提供延迟匹配(以类似glob的方式)和regexp匹配。例如,以下两个片段最终会产生相同的效果:

@mylib.rule('static/*.html')
def myfunc():
    pass

@mylib.rule(r'^static/([^/]+)\.html')
def myfunc():
    pass

AFAIK r''仅对Python解析器有用,它实际上在解析后创建了一个标准str实例(唯一的区别是它保留了\)。

有人知道一种方法可以告诉彼此吗?

我不想为同一目的提供两个备用装饰器,或者更糟糕的是,手动解析字符串以确定它是否是正则表达式。

3 个答案:

答案 0 :(得分:13)

你无法区分它们。每个原始字符串文字也可以写为标准字符串文字(可能需要更多引用),反之亦然。除此之外,我肯定会给两个装饰者添加不同的名字。他们不做同样的事情,做不同的事情。

示例(CPython):

>>> a = r'^static/([^/]+)\.html'; b = '^static/([^/]+)\.html'
>>> a is b
True

因此,在此特定示例中,原始字符串文字和标准字符串文字甚至会产生相同的字符串对象。

答案 1 :(得分:11)

您无法判断字符串是否在事后被定义为原始字符串。就个人而言,我实际上会使用一个单独的装饰器,但是如果你不想这样做,你可以使用一个命名参数(例如@rule(glob="*.txt")表示globs,@rule(re=r".+\.txt")表示正则表达式。

或者,要求用户提供已编译的正则表达式对象,如果他们想要使用正则表达式,例如@rule(re.compile(r".+\.txt")) - 这很容易被发现,因为它的类型不同。

答案 2 :(得分:1)

术语“原始字符串”令人困惑,因为它听起来像是一种特殊类型的字符串 - 实际上,它只是文字的一种特殊语法,它告诉编译器不做任何解释字符串中的'\'字符。不幸的是,这个术语被用来描述这种编译时行为,但许多初学者认为它带有一些特殊的运行时特性。

我更喜欢称它们为“原始字符串文字”,以强调它是使用not-interpret-backslashes语法定义字符串文字,这使得它们“原始” 。原始字符串文字和普通字符串文字都创建字符串(或str s),结果变量是任何其他字符串。由原始字符串文字创建的字符串在各方面都与使用转义反斜杠非原始定义的相同字符串等效。