究竟什么是“原始字符串正则表达式”,你如何使用它?(What exactly is a “raw s

2019-06-18 12:34发布

从Python文档的正则表达式 ,关于'\'字符:

解决的办法是使用Python的raw字符串表示的正则表达式模式; 反斜杠不会以任何特殊的方式与前缀字符串文字处理的'r' 。 所以r"\n"是含有两个字符的字符串'\''n' ,而"\n"是含有一个换行符一个字符的字符串。 通常的模式将在Python代码中使用这种原始字符串符号来表示。

这是什么原始字符串符号? 如果您使用原始字符串格式,这是否意味着"*"被视为AA文字字符,而不是一个零或更多的指标呢? 这显然不可能是正确的,否则正则表达式将完全失去它的力量。 不过,如果它是一个原始字符串,它是如何认识换行符如果"\n"是名副其实的反斜线和"n"

我不明白。

编辑赏金:

我想了解一个原始字符串匹配的正则表达式换行,制表符和字符集,如\w单词或\d为数字或诸如此类的东西全部,如果原始字符串模式不承认反斜线东西比普通的字符。 我真的可以使用一些很好的例子。

Answer 1:

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") :这是更容易分离正则表达式的编译字符串,并分别了解他们理解。

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

字符串s包含八个字符: 反斜杠 ,一个s,一个反斜杠 ,一个T,然后四个字符Word

:发生了标签和空格字符是什么? :在Python语言水平,串s没有标签空格字符。 它从四个大字: 反斜杠 ,S, 反斜杠 ,T。 正则表达式系统,同时,把该字符串作为在正则表达式语言,它的意思是“由匹配空白字符,制表符,和四个字符的字符串的源代码Word

:你如何匹配,如果这被视为反弹-S和反斜线-T? :也许问题是清晰的,如果的话“你”和“那个”都提出了更具体的:如何在正则表达式系统相匹配的表达式反弹-S和反斜线-T? 由于“任何空白字符”和“ 制表符”。

:或者,如果你有3个字符的字符串反斜线正换行符? :在Python语言中,3个字符的字符串反斜杠正换行符可以表示为常规字符串"\\n\n" ,或原始加常规串r"\n" "\n" ,或以其他方式。 正则表达式系统匹配的3个字符的字符串反斜杠正换行符当它发现任何两个连续的换行符

NB的所有实例和文档引用到Python 2.7。

更新 :澄清成立由@Vladislav Zorov和@ m.buettner的答案,从@Aerovistae的后续问题。



Answer 2:

大多数的这些问题有很多他们的话,也许很难找到答案您的具体问题。

如果使用常规的字符串,以及像“\ t”的对正则表达式解析器的模式通过,Python会翻译是文字与它(0×09)的标签字节的缓冲区。

如果您使用的是原始字符串,你像R“\ t”的模式,以正则表达式解析器通过,Python没有做任何解释,并创建带有两个字节的缓冲区:“\”和“T”。 (0x5c,0x74)。

正则表达式解析器知道如何处理序列“\ t”做 - 它匹配,对一个标签。 它也知道做什么用的字符×09做 - 这也是相匹配的标签。 在大多数情况下,其结果将是没有什么区别。

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



Answer 3:

与使用普通字符串来编写包含一个正则表达式的问题\是你最终不得不写\\每一个\ 。 所以字符串文字"stuff\\things"r"stuff\things"产生相同的字符串。 如果你想写,对反斜杠相匹配的正则表达式这得到特别有用。

在使用普通字符串,但该字符串匹配的正则表达式\"\\\\"

为什么? 因为我们要逃避\两次:一次正则表达式语法,并曾经为字符串语法。

你可以使用三引号包括换行,像这样:

r'''stuff\
things'''

需要注意的是,通常,蟒蛇会像对待\ -newline作为续行,但这不是在原始字符串的情况。 还要注意的是反斜杠仍逃避原始字符串引号,但留给自己。 因此,原始字符串字面r"\""生产线\" 。 这意味着您不能结束原始字符串字面用反斜杠。

见Python文档的词法分析部分以获取更多信息。



Answer 4:

你似乎的想法,正则表达式不是Python中的一部分,而是有自己的解析器和编译器不同的编程语言来挣扎。 原始字符串帮助你得到一个正则表达式的“源代码”安全的正则表达式解析器,它将然后分配意味着像字符序列\d\w\n等...

存在的问题,因为Python和正则表达式使用\作为转义字符,这是,顺便说一句,一个巧合-还有其他的转义字符语言(如“`n”表示换行,但即使在那里,你必须使用“\ n在正则表达式)“。 其优点是,你不需要在这些语言生和非原始字符串之间的区别,他们不会都试图将文本转换和屠夫,因为他们不同的转义序列反应。



Answer 5:

有关Python的手册节(“字符串和字节的文字”)的原始字符串字面解释清楚:

字符串和字节文字可以任选地以字母“R”或“R”前缀; 这样的字符串被称为原始字符串和治疗反斜杠作为文字字符。 其结果是,在字符串中,“\ U”和“\ U”在原始字符串逃逸没有特殊对待。 虽然Python 2.x中的原始的Unicode文本表现不同比Python 3.x的是不支持的“UR”语法。

新的3.3版:原始字节文字的“RB”前缀已经被添加为“BR”的代名词。

在3.3版本的新功能:支持unicode的传统文字(u'value')被再简化的双重的Python 2.x和3.x代码库的维护。 见PEP 414了解更多信息。

在三引号字符串,转义换行和允许使用引号(和保留),除了在三个连续的转义引号终止字符串。 (A“引用”是用来打开串,即,或者“或”的字符。)

除非一个“R”或“R”的前缀是目前,逃避串序列被解释根据类似于由标准C.使用的识别转义序列规则:

转义序列含义说明

\换行符反斜杠和换行符忽略
\反斜杠()
\ '单引号(')
\ “双引号(”)
\一个ASCII贝尔(BEL)
\ b ASCII Backspace键(BS)
\˚FASCII换页(FF)
\ n ASCII换行(LF)
\ r ASCII回车(CR)
\吨ASCII水平制表(TAB)符\ v ASCII垂直制表符(VT)
\ OOO性格与八进制值OOO(1,3)
\ XHH性格与十六进制值HH(2,3)

逃生只有在字符串中识别的序列是:

转义序列在Unicode数据库含义注\ N {名称}字符命名名称(4)为\ uXXXX字符具有16位十六进制值XXXX(5)\ Uxxxxxxxx字符具有32位十六进制值XXXXXXXX(6)

笔记:

  1. 由于在标准C,最多三个八进制数字被接受。

  2. 不同于标准C,需要整整两个十六进制数字。

  3. 在字面一个字节,十六进制和八进制表示逃逸用给定的值的字节。 在一个字符串,这些转义表示与给定值的Unicode字符。

  4. 改变在3.3版本:增加了对名称的别名[1]支持。

  5. 其形成的替代物对零件的个体代码单元可以使用该转义序列进行编码。 正好四个十六进制数字是必需的。

  6. 任何Unicode字符可被编码这种方式,但基本多语种平面(BMP)之外的字符将利用代理对Python是否编译使用16位编码单元(缺省值)进行编码。 整整8个六角数字是必需的。

不同于标准C,所有无法识别的转义序列留在串不变,即反斜线留在的字符串中。 (调试时此行为是有用的:如果一个转义序列被错误地输入,所得到的输出更容易识别为虚线)。同样重要的是要注意,仅在字符串识别的转义序列落入无法识别的逃逸为字节的类别文字。

即使在原始字符串,字符串引号可以用反斜杠转义,但反斜线仍然在字符串中; 例如,R“\””是一个有效的字符串文字由两个字符:一个反斜线和双引号; R‘\’不是有效的字符串文字(甚至一个原始字符串在奇数反斜线不能结束)。具体地,原始字符串不能以反斜线结束(因为反斜杠将逸出以下引号字符)。还请注意,一个反斜线后跟换行符被解释为这两个字符作为字符串的一部分,而不是作为续行。



文章来源: What exactly is a “raw string regex” and how can you use it?