python正则re模块字符串转义
python正则表达式转义注意事项
⽆论哪种语⾔,在使⽤正则表达式的时候都避免不了⼀个问题,就是在匹配元字符的时候,需要对元字符进⾏转义,让
正则表达式引擎将其当做普通字符来匹配。本⽂主要以python为例,说明⼀下转义中需要注意的问题。
python的正则表达式中需要转义的元字符有以下⼏个:
.
^
$
*
+
\
[]
|
{}
()
python中对元字符的转义使⽤双反斜杠 \ 来表⽰
# 普通元字符的转义
string ='$'
# 不转义
print re.findall('$', string)
#>>> ['', '']
# 双反斜杠转义
print re.findall('\\$', string)
#>>> ['$']
# 单反斜杠转义
print re.findall('\$', string)
#>>> ['$']
看上⾯的例⼦⼤家可能会发现,使⽤⼀个反斜杠 \ 也可以达到转义的效果,那为什么还要写两个呢?这得先搞清楚python的字符串转义(不是正则表达式转义),python本⾝使⽤ \ 来转义⼀些特殊字符,⽐如在字符串中加⼊引号的时候,为了防⽌和字符串本⾝的引号冲突,使⽤ \ 来转义,⼀般情况下这个也不会引起什么问题,但是当你要使⽤ \ 来转义 \ 的时候,就⽐较混乱了,⽐如我们想要输出⼀个 \,得写两个 \ ,否则会报语法错误,因为 \ 把后⾯的引号给转义了,
s ='i\'m superman'
print s
#>>> i'm superman
# 错误写法
# print '\'
# 正确写法
print'\\'
#>>> \
# 原⽣字符串
print r'\\'
#>>> \\
必须使⽤ \ 将 \ 转义⼀下使其不具备转义功能,才可以正确输出,当使⽤原⽣字符串的时候,输出显⽰了两个 \ ,看起来好像是写⼏个输出⼏个的样⼦,如果这样想的话,你可以试⼀下,看能不能输出奇数个 \。
先来说⼀下什么是原⽣字符串,其实就是不进⾏特殊处理的字符串,所谓特殊处理,貌似就是针对转
义的,原⽣字符串
的诞⽣本⾝就是为了解决转义的时候写了太多 \ 的问题,但是为什么使⽤了原⽣字符串仍然不能只输出⼀个 \ 呢?其实这应该算是⼀个bug,就是python的字符串不能以奇数个 \ 结尾,这样的写法会被认为是将结尾的引号进⾏了转义,导致语法错误。
虽然原⽣字符串并不是很完美,但它已经可以帮我们解决很⼤⼀部分问题了。⽐如当你想匹配 \ 的时候,原⽣字符串可以让你少写⼀半的 \,既节省代码量,⼜增加可读性。
_string ='\\\\'
print _string
#>>> \\
# 字符串
for i in re.findall('\\\\', _string):
print i
#>>> \
#>>> \
# 原⽣字符串
for i in re.findall(r'\\', _string):
print i
#>>> \
#>>> \
说了这么多也没说为什么在写正则表达式的时候⼀个 \ 也可以起到转义的作⽤。我们先来分析⼀下⼀个字符串被正则表
达式引擎解析的过程,⼀共有4步:
1. ⾸先正则表达式是⼀个python的字符串
2. 字符串本⾝会先进⾏转义处理
3. 正则表达式引擎得到处理之后的字符串后再对字符串进⾏正则表达式引擎⾃⼰的处理
4. 开始匹配
# 字符串
# '\\\\'
# 经过python处理之后
# '\\'
# 正则表达式引擎接收到的
# '\\'
# 正则表达式引擎进⾏转义处理后可以匹配到 \
# '\'
⽽当使⽤原⽣字符串的时候就变为了3步
# 原⽣
# '\\'
# 不再处理
# '\\'
# 正则表达式引擎接收到的
# '\\'
# 正则表达式引擎进⾏转义处理
# '\'
下⾯是最重要的⼀个,当使⽤⼀个 \ 转义的时候,python会识别不了转义序列,于是它就不做任何处理,直接传给了
正则表达式引擎。这就解释了为什么⼀个 \也可以转义。这个不算bug,虽然⽅便了使⽤,但会让⼈很迷惑,有利有弊吧。
python正则表达式不包含# 原⽣
# '\$'
# 识别不了不进⾏处理
# '\$'
# 正则表达式引擎接收到的
# '\$'
# 正则表达式引擎进⾏转义处理# '$'
例⼦:
# 匹配 \d+
_string ='i am \d+'
print re.findall('\\\\d\\+', _string)[0] #>>> \d+
print re.findall(r'\\d\+', _string)[0] #>>> \d+
# 匹配 []
_string ='i am []'
print re.findall('\\[\\]', _string)[0] #>>> []
print re.findall('\[\]', _string)[0] #>>> []
print re.findall(r'\[\]', _string)[0] #>>> []
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论