您对字符串和字符串文字之间的区别感到困惑。
字符串文字是您放在"
or之间'
的内容,python 解释器解析此字符串并将其放入内存。如果您将字符串文字标记为原始字符串文字(使用r'
),则 python 解释器在将其放入内存之前不会更改该字符串的表示,但一旦它们被解析,它们就会以完全相同的方式存储。
这意味着在内存中没有原始字符串之类的东西。以下两个字符串都以相同的方式存储在内存中,不知道它们是否是原始的。
r'a regex digit: \d' # a regex digit: \d
'a regex digit: \\d' # a regex digit: \d
这两个字符串都包含\d
并且没有什么可以说它来自原始字符串。因此,当您将此字符串传递给re
模块时,它会看到有 a\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)
再次(因为\d
不是有效的字符串转义,它不会被更改,请参阅我的第一次编辑)re.sub
接收两个字符串(\d+)/(\d+)/(\d+)
和\3-\1-\2
. 因为\d
不会被 python 解释器改变r'(\d+)/(\d+)/(\d+)' == '(\d+)/(\d+)/(\d+)'
。如果您了解我的第一次编辑,那么希望您应该了解为什么这两种情况的行为相同。
text2_re2 = re.sub(r'(\d+)/(\d+)/(\d+)', '\3-\1-\2', text2)
这种情况有点不同\1
,因为\2
和\3
都是有效的转义序列,它们被替换为unicode 字符,其十进制表示由数字给出。这很复杂,但基本上可以归结为:
\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
这意味着它re.sub
接收第一个字符串,就像它在前两个示例 ( (\d+)/(\d+)/(\d+)
) 中所做的那样,但第二个字符串实际上是<start-of-heading>/<start-of-text>/<end-of-text>
. 所以re.sub
用第二个字符串完全替换匹配,但由于三个 (\1
或\2
)\3
都不是可打印的字符,python 只打印一个普通的占位符字符。
text2_re3 = re.sub('(\d+)/(\d+)/(\d+)', '\3-\1-\2', text2)
这与第三个示例类似,因为r'(\d+)/(\d+)/(\d+)' == '(\d+)/(\d+)/(\d+)'
正如第二个示例中所解释的那样。