Python正则expression式中的反斜杠
我对正则expression式中的反斜杠感到困惑。 在正则expression式中, \
有一个特殊的含义,例如\d
表示十进制数字。 如果你在反斜杠前添加一个反斜杠,这个特殊的含义就会丢失。 在正则expression式中,人们可以阅读:
也许最重要的元字符是反斜杠
\
。 和Pythonstring一样,反斜线后面可以跟着各种字符来表示各种特殊的序列。 它也被用来转义所有的元字符,所以你仍然可以在模式中匹配它们; 例如,如果你需要匹配一个[
或\
,你可以在它们前面加一个反斜杠去除它们的特殊含义:\[
或\\
。
所以print(re.search('\d', '\d'))
给出None
因为\d
匹配任何十进制数字,但\d
没有。
我现在希望print(re.search('\\d', '\d'))
匹配\d
但答案仍然是None
。
只有print(re.search('\\\d', '\d'))
作为输出<_sre.SRE_Match object; span=(0, 2), match='\\d'>
<_sre.SRE_Match object; span=(0, 2), match='\\d'>
。
有人有解释吗?
混淆是因为反斜杠字符\
被用作两个不同级别的转义。 首先,Python解释器本身在re
模块看到你的string之前执行\
replace。 例如\n
被转换成一个换行符, \t
被转换成一个制表符,等等。为了得到一个实际的\
字符,你也可以转义它,所以\\
给出一个\
字符。 如果\
的字符不是公认的转义字符,那么\
就像任何其他字符一样被处理并通过,但是我不推荐依赖这个字符。 相反,总是逃避\
字符通过加倍,即\\
。
如果你想看看Python如何扩展你的string转义,只需打印出string。 例如:
s = 'a\\b\tc' print s
如果s
是一个聚合数据types的一部分,例如一个列表或一个元组,并且如果你打印这个聚合,Python将把这个string括在单引号中,并且包含\
escapes(以规范的forms),所以要注意你的string正在打印。 如果你只是在解释器中input一个带引号的string,它也会用'\'转义符把它显示在引号中。
一旦你知道你的string是如何被编码的,那么你可以考虑一下re
模块会用它来做什么。 例如,如果你想在一个string中转义\
你传递给re
模块,你将需要通过\\
来re
,这意味着你将需要在引用的Pythonstring中使用\\\\
。 Pythonstring将以\\
结尾,而re
模块会将其视为单个文字\
字符。
在Pythonstring中包含\
字符的另一种方法是使用原始string,例如r'a\b'
等同于"a\\b"
。
Python自己的stringparsing(部分)来自你的方式。
如果你想看看看到什么,请input
print '\d' print '\\d' print '\\\d'
在Python命令提示符下。 你会发现\d
和\\d
都会导致\d
,而后者则被Pythonstringparsing器所关注。
如果您想避免这些麻烦,请使用re模块文档中build议的原始string: r'\\d'
将会被RE模块看到。
正则expression式之前的一个r字符告诉search()指定正则expression式是一个原始string。 这允许反斜杠在正则expression式中用作常规字符,而不是在字符的转义序列中使用。 让我解释 …
在re模块的search方法处理传递给它的string之前,Python解释器首先传递string。 如果string中存在反斜杠,则Python解释器必须决定每个string是否是Python转义序列的一部分(例如\ n或\ t)。
注意:在这一点上,Python并不关心“\”是否是一个正则expression式元字符。
如果“\”后面紧跟一个可识别的Python转义字符(t,n等),则反斜杠和转义字符被replace为实际的Unicode或8位字符。 例如,'\ t'将replace为制表符的ASCII字符。 否则,它被传递并被解释为“\”字符。
考虑以下几点。
>>> s = '\t' >>> print ("[" + s + "]") >>> [ ] // an actual tab character after preprocessing >>> s = '\d' >>> print ("[" + s + "]") >>> [\d] // '\d' after preprocessing
有时我们想要在string中包含一个包含'\'的字符序列,而不会被Python解释为转义序列。 为了做到这一点,我们用'\'来避开'\'。 现在,当Python看到“\”时,它将用一个“\”字符replace两个反斜杠。
>>> s = '\\t' >>> print ("[" + s + "]") >>> [\t] // '\t' after preprocessing
在Python解释器对这两个string进行传递之后,它们被传递给re模块的search方法。 search方法分析正则expression式string以标识正则expression式的元字符。
现在'\'也是一个特殊的正则expression式元字符,被解释为一个,而且在执行re search()方法的时候被转义。
考虑下面的电话。
>>> match = re.search('a\\t','a\\t') //Match is None
在这里,比赛是无。 为什么? 让我们看看Python解释器通过之后的string。
String 1: 'a\t' String 2: 'a\t'
那么为什么匹配等于无? 当search()解释string1时,由于它是正则expression式,所以反斜杠被解释为元字符,而不是普通字符。 然而,string2中的反斜杠不是正则expression式,并且已经由Python解释器处理,所以它被解释为普通字符。
所以search()方法正在寻找string'a \ t'中的'escape-t',这不是匹配的。
为了解决这个问题,我们可以告诉search()方法不要把'\'解释为元字符。 我们可以通过转义来做到这一点。
考虑下面的电话。
>>> match = re.search('a\\\\t','a\\t') // Match contains 'a\t'
再次,让我们看看Python解释器通过之后的string。
String 1: 'a\\t' String 2: 'a\t'
现在,当search()方法处理正则expression式时,它会看到第二个反斜杠被第一个转义,而不应被视为元字符。 因此它将string解释为'a \ t',它与string2匹配。
将search()视为一个字符的替代方法是在正则expression式之前放置一个r。 这告诉Python解释器不要预处理string。
考虑这个。
>>> match = re.search(r'a\\t','a\\t') // match contains 'a\t'
这里的Python解释器不会修改第一个string,但会处理第二个string。 传递给search()的string是:
String 1: 'a\\t' String 2: 'a\t'
如前例所示,search将“\”解释为单个字符“\”,而不是元字符,因此与string2匹配。
- 正确expression一个词的完全匹配
- 正则expression式:在不同的上下文中使用行开始/结束行符号(^或$)
- 正则expression式最后一次发生?
- 在正则expression式中,“?”和“?-i”是什么意思?
- 删除string中的分隔符之间的文本(使用正则expression式?)
- 正则expression式匹配/replaceJavaScript注释(多行和内联)
- 使用preg_matchparsingYouTubevideoID
- Javascript正则expression式 – replace非数字字符
- 如何在Objective C(NSRegularExpression)中编写正则expression式?