究竟什么是“原始字符串正则表达式”以及如何使用它?

新手上路,请多包涵

从关于 regex 的 python 文档中,关于 '\' 字符:

解决方案是对正则表达式模式使用 Python 的原始字符串表示法;在以 'r' 为前缀的字符串文字中,不以任何特殊方式处理反斜杠。 So r"\n" is a two-character string containing '\' and 'n' , while "\n" is a one-character string containing a newline.通常模式将使用这种原始字符串表示法在 Python 代码中表示。

这个原始字符串表示法是什么?如果您使用原始字符串格式,这是否意味着 "*" 被视为文字字符而不是零或多个指示符?这显然是不对的,否则正则表达式将完全失去它的力量。但是,如果它是原始字符串,如果 "\n" 字面上是反斜杠和 "n" ,它如何识别换行符?

我不跟

编辑赏金:

我试图了解原始字符串正则表达式如何匹配换行符、制表符和字符集,例如 \w 用于单词或 \d 用于数字或所有诸如此类的东西,如果原始字符串模式不t 将反斜杠识别为普通字符以外的任何东西。我真的可以使用一些很好的例子。

原文由 temporary_user_name 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 532
2 个回答

Zarkonnen 的回答确实回答了您的问题,但不是直接回答。让我尝试更直接,看看我是否可以从 Zarkonnen 那里获得赏金。

如果您停止使用术语“原始字符串正则表达式”和“原始字符串模式”,您可能会发现这更容易理解。这些术语混淆了两个独立的概念:Python 源代码中特定字符串的表示,以及该字符串表示的正则表达式。

事实上,将它们视为两种不同的编程语言很有帮助,每种语言都有自己的语法。 Python 语言具有源代码,其中包括构建具有特定内容的字符串并调用正则表达式系统。正则表达式系统的源代码驻留在字符串对象中,并匹配字符串。两种语言都使用反斜杠作为转义字符。

首先,了解字符串是字符序列(即字节或 Unicode 代码点;这里的区别并不重要)。在 Python 源代码中有多种表示字符串的方法。 原始字符串 只是这些表示之一。如果两种表示产生相同的字符序列,则它们产生等效的行为。

想象一个 2 个字符的字符串,由 反斜杠 字符和后跟 n 字符组成。如果您知道 反斜杠 的字符值为 92,而 n 的字符值为 110,那么此表达式将生成我们的字符串:

 s = chr(92)+chr(110)
print len(s), s

2 \n

传统的 Python 字符串表示法 "\n" 不会生成此字符串。相反,它会生成一个带有换行符的单字符字符串。 Python 文档 2.4.1。字符串文字 表示,“反斜杠 (\) 字符用于转义具有特殊含义的字符,例如换行符、反斜杠本身或引号字符。”

 s = "\n"
print len(s), s

1


(请注意,在此示例中换行符不可见,但如果仔细观察,您会在“1”之后看到一个空行。)

要获得我们的双字符字符串,我们必须使用另一个 反斜杠 字符来转义原始 反斜杠 字符的特殊含义:

 s = "\\n"
print len(s), s

2 \n

如果你想表示其中有很多 反斜杠 字符的字符串怎么办? Python 文档 2.4.1。字符串文字 继续,“字符串文字可以选择使用字母‘r’或‘R’作为前缀;此类字符串称为 _原始字符串_,并使用不同的规则来解释反斜杠转义序列。”这是我们的两个字符的字符串,使用原始字符串表示:

 s = r"\n"
print len(s), s

2 \n

所以我们有三种不同的字符串表示形式,都给出相同的字符串或字符序列:

 print chr(92)+chr(110) == "\\n" == r"\n"
True

现在,让我们转向正则表达式。 Python 文档,7.2。 re - 正则表达式操作 说,“正则表达式使用反斜杠字符(’\‘)来指示特殊形式或允许使用特殊字符而不调用它们的特殊含义。这与Python对字符串文字中用于相同目的的相同字符……”

如果你想要一个匹配换行符的 Python 正则表达式对象,那么你需要一个 2 字符的字符串,由 反斜杠 字符和后跟 n 字符组成。以下代码行全部设置 prog 为识别换行符的正则表达式对象:

 prog = re.compile(chr(92)+chr(110))
prog = re.compile("\\n")
prog = re.compile(r"\n")

那么为什么 “通常模式将使用这种原始字符串表示法在 Python 代码中表达”。 ?因为正则表达式通常是静态字符串,可以方便地表示为字符串文字。从可用的不同字符串文字符号来看,当正则表达式包含 反斜杠 字符时,原始字符串是一个方便的选择。

问题

:表达式 re.compile(r"\s\tWord") 怎么样? A : 将字符串从正则表达式编译中分离出来,分开理解更容易理解。

 s = r"\s\tWord"
prog = re.compile(s)

字符串 s 包含八个字符: _反斜杠_、 s 、 _反斜杠_、 t ,然后是四个字符 Word

:制表符和空格字符会怎样? :在 Python 语言级别,字符串 s 没有 制表符空格 字符。它以四个字符开头: _反斜杠_、 s 、 _反斜杠_、 t 。同时,正则表达式系统将该字符串视为正则表达式语言中的源代码,意思是“匹配由一个空白字符、一个制表符和四个字符 Word 组成的字符串。

:如果将其视为反斜杠-s 和反斜杠-t,您如何匹配它们? A : 如果把’you’ 和’that’ 说得更具体一些,问题可能会更清楚:正则表达式系统如何匹配表达式backlash-s 和backslash-t?作为“任何空白字符”和“ 制表 符”。

:或者如果你有 3 个字符的字符串反斜杠-n-换行符怎么办? A : 在Python语言中,3个字符的字符串反斜杠-n-换行可以表示为常规字符串 "\\n\n" ,或者原始加常规字符串 r"\n" "\n" ,或者其他方式。正则表达式系统在找到任意两个连续的 换行符 时匹配 3 个字符的字符串 backslash-n-newline。

注意所有示例和文档参考均针对 Python 2.7。

更新:合并了@Vladislav Zorov 和@m.buettner 的回答以及@Aerovistae 的后续问题的澄清。

原文由 Jim DeLaHunt 发布,翻译遵循 CC BY-SA 4.0 许可协议

这些问题中的大多数都有很多单词,也许很难找到您特定问题的答案。

如果您使用常规字符串并将类似“\t”的模式传递给 RegEx 解析器,Python 会将该文字转换为包含制表符字节 (0x09) 的缓冲区。

如果您使用原始字符串并将类似 r”\t” 的模式传递给 RegEx 解析器,Python 不会进行任何解释,它会创建一个包含两个字节的缓冲区:’\’ 和 ’t’。 (0x5c,0x74)。

RegEx 解析器知道如何处理序列“\t”——它将它与制表符进行匹配。它还知道如何处理 0x09 字符——也匹配制表符。在大多数情况下,结果将无法区分。

所以理解正在发生的事情的关键是认识到这里使用了两个解析器。第一个是 Python 解析器,它将您的字符串文字(或原始字符串文字)转换为字节序列。第二个是 Python 的正则表达式解析器,它将字节序列转换为已编译的正则表达式。

原文由 Geoff Gerrietts 发布,翻译遵循 CC BY-SA 3.0 许可协议

推荐问题