Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/matlab/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python中的原始字符串和正则表达式_Python_Regex_Escaping_Backslash_Rawstring - Fatal编程技术网

Python中的原始字符串和正则表达式

Python中的原始字符串和正则表达式,python,regex,escaping,backslash,rawstring,Python,Regex,Escaping,Backslash,Rawstring,我对以下代码中的原始字符串有一些混淆: import re text2 = 'Today is 11/27/2012. PyCon starts 3/13/2013.' text2_re = re.sub(r'(\d+)/(\d+)/(\d+)', r'\3-\1-\2', text2) print (text2_re) #output: Today is 2012-11-27. PyCon starts 2013-3-13. print (r'(\d+)/(\d+)/(\d+)') #ou

我对以下代码中的原始字符串有一些混淆:

import re

text2 = 'Today is 11/27/2012. PyCon starts 3/13/2013.'
text2_re = re.sub(r'(\d+)/(\d+)/(\d+)', r'\3-\1-\2', text2)
print (text2_re) #output: Today is 2012-11-27. PyCon starts 2013-3-13.

print (r'(\d+)/(\d+)/(\d+)') #output: (\d+)/(\d+)/(\d+)
就我对原始字符串的理解而言,如果没有r,则\被视为转义字符;使用r,反斜杠\按字面意思处理

然而,在上述代码中我无法理解的是: 在正则表达式行5中,即使存在一个r,内部的“\d”也被视为一个数字[0-9],而不是一个反斜杠\加上一个字母d

在第二个打印行8中,所有字符都被视为原始字符串

有什么区别

附加版: 我做了以下四种变化,有无r

import re

text2 = 'Today is 11/27/2012. PyCon starts 3/13/2013.'
text2_re = re.sub(r'(\d+)/(\d+)/(\d+)', r'\3-\1-\2', text2)
text2_re1 = re.sub('(\d+)/(\d+)/(\d+)', r'\3-\1-\2', text2)
text2_re2 = re.sub(r'(\d+)/(\d+)/(\d+)', '\3-\1-\2', text2)
text2_re3 = re.sub('(\d+)/(\d+)/(\d+)', '\3-\1-\2', text2)

print (text2_re)
print (text2_re1)
print (text2_re2)
print (text2_re3)
并获得以下输出:


你能具体解释一下这四种情况吗

不是所有的
\
都会引起问题。Python有一些内置的东西,如
\b
等。所以现在如果
r
不存在,Python将考虑<代码> \b/COD>作为正则表达式,而不是<代码> Word边界>代码>。当它与<代码> R< /代码>模式一起使用时,代码< > \b/COD>完全保留。这是外行语言。技术上没有太多。<代码> \d>代码>在Python中不是特殊的内置,因此即使没有<代码> R>代码>模式,也将是安全的。

您可以在这里查看列表。这是python理解并将解释的列表。例如
\b
\n
而不是
\d


在第一个
print
模式中,
\d
解释是由正则表达式模块而不是python完成的。在第二个
print
模式中,它是由python完成的。在
r
模式中,它将保持原样。

您必须对python解释器和
re
模块进行区分

在python中,如果未绘制字符串,则后跟字符的反斜杠可以表示特殊字符。例如,
\n
表示换行符,
\r
表示回车,
\t
表示制表符,
\b
表示非破坏性的退格。python字符串中的
\d
本身并不意味着任何特殊的含义

然而,在正则表达式中,有一堆字符在python中并不总是有任何意义。但问题是,“不总是”。有一件事可能会被误解,那就是
\b
,在python中是一个退格,在正则表达式中是一个单词边界。这意味着,如果您将一个未经敬畏的
\b
传递给正则表达式的正则表达式部分,那么在传递给正则表达式函数之前,这个
\b
将被退格所取代,并且它在那里没有任何意义。因此,您必须绝对地传递带有反斜杠的
b
,要做到这一点,您要么转义反斜杠,要么原始字符串

回到您关于
\d
的问题,
\d
在python中没有任何特殊意义,因此它没有被触及。作为正则表达式传递的相同的
\d
由正则表达式引擎转换,正则表达式引擎是python解释器的独立实体


每个问题的编辑:

import re

text2 = 'Today is 11/27/2012. PyCon starts 3/13/2013.'
text2_re = re.sub(r'(\d+)/(\d+)/(\d+)', r'\3-\1-\2', text2)
text2_re1 = re.sub('(\d+)/(\d+)/(\d+)', r'\3-\1-\2', text2)
text2_re2 = re.sub(r'(\d+)/(\d+)/(\d+)', '\3-\1-\2', text2)
text2_re3 = re.sub('(\d+)/(\d+)/(\d+)', '\3-\1-\2', text2)

print(text2_re)
print(text2_re1)
print(text2_re2)
print(text2_re3)
前两个应该是直截了当的
re.sub
通过匹配数字和正斜杠,并以不同的顺序替换为连字符来完成任务。由于
\d
在python中没有任何特殊意义,
\d
传递给
re.sub
,无论表达式是否绘制

第三次和第四次出现是因为您没有为replace表达式绘制字符串
\1
\2
\3
在python中有特殊含义,分别表示白色(或未填充的)笑脸、黑色(填充的)笑脸和心形(如果无法显示字符,则得到这些“字符框”)。因此,您不是用捕获的组替换字符串,而是用特定字符替换字符串


您会被字符串和字符串文字之间的差异弄糊涂

字符串文字是介于
之间的文字,python解释器解析该字符串并将其放入内存。如果将字符串文字标记为原始字符串文字(使用
r'
)然后,python解释器在将该字符串放入内存之前不会更改该字符串的表示形式,但一旦对它们进行了解析,它们将以完全相同的方式存储

这意味着在内存中没有原始字符串。以下两个字符串在内存中以相同的方式存储,不知道它们是否为原始字符串

r'a regex digit: \d'  # a regex digit: \d
'a regex digit: \\d'  # a regex digit: \d
这两个字符串都包含
\d
,不能说这是来自原始字符串。因此,当您将此字符串传递到
re
模块时,它会看到有一个
\d
,并将其视为一个数字,因为
re
模块不知道该字符串来自原始字符串文本

在您的特定示例中,要获得后跟文字d的文字反斜杠,可以使用
\\d
如下所示:

import re

text2 = 'Today is 11/27/2012. PyCon starts 3/13/2013.'
text2_re = re.sub(r'(\\d+)/(\\d+)/(\\d+)', r'\3-\1-\2', text2)
print (text2_re) #output: Today is 11/27/2012. PyCon starts 3/13/2013.
或者,在不使用原始字符串的情况下:

import re

text = 'Today is 11/27/2012. PyCon starts 3/13/2013.'
text_re = re.sub('(\\d+)/(\\d+)/(\\d+)', '\\3-\\1-\\2', text2)
print (text_re) #output: Today is 2012-11-27. PyCon starts 2013-3-13.

text2 = 'Today is 11/27/2012. PyCon starts 3/13/2013.'
text2_re = re.sub('(\\\\d+)/(\\\\d+)/(\\\\d+)', '\\3-\\1-\\2', text2)
print (text2_re) #output: Today is 11/27/2012. PyCon starts 3/13/2013.
我希望这能有所帮助

编辑:我不想把事情复杂化,但因为
\d
不是一个有效的转义序列,python不会更改它,所以
'\d'==r'\d'
是正确的。由于
\
是一个有效的转义序列,它会被更改为
\
,因此您会得到
'\d'='='\\d'==r'\d'
的行为。字符串会变得混乱有时唱歌

Edit2:要回答您的编辑,让我们具体看一下每一行:

text2_re = re.sub(r'(\d+)/(\d+)/(\d+)', r'\3-\1-\2', text2)
re.sub
接收两个字符串
(\d+)/(\d+)/(\d+)
\3-\1-\2
。希望这能像您现在期望的那样运行

text2_re1 = re.sub('(\d+)/(\d+)/(\d+)', r'\3-\1-\2', text2)
再次(因为
\dtext2_re2 = re.sub(r'(\d+)/(\d+)/(\d+)', '\3-\1-\2', text2)
\1  # stands for the ascii start-of-heading character
\2  # stands for the ascii start-of-text character
\3  # stands for the ascii end-of-text character
text2_re3 = re.sub('(\d+)/(\d+)/(\d+)', '\3-\1-\2', text2)
>>> print "\nlolwtfbbq"

lolwtfbbq
>>> print r"\nlolwtfbbq"
\nlolwtfbbq
>>>