python正则表达式转义注意事项

不管哪一种语言,在使用正则表达式的时候都避免不了一个问题,就是在匹配元字符的时候,须要对元字符进行转义,让python

正则表达式引擎将其当作普通字符来匹配。本文主要以python为例,说明一下转义中须要注意的问题。正则表达式

python的正则表达式中须要转义的元字符有如下几个:spa

    1. .
    2. ^
    3. $
    4. *
    5. +
    6. ?
    7. \\
    8. []
    9. |
    10. {}
    11. ()

python中对元字符的转义使用双反斜杠 \\ 来表示code

# 普通元字符的转义
_string = '''
!@#$%^&
'''

# 不转义
print re.findall('$', _string)
#>>> ['', '']

# 双反斜杠转义
print re.findall('\\$', _string)
#>>> ['$']

# 单反斜杠转义
print re.findall('\$', _string)
#>>> ['$']

看上面的例子你们可能会发现,使用一个反斜杠 \ 也能够达到转义的效果,那为何还要写两个呢?这得先搞清楚pythonblog

的字符串转义(不是正则表达式转义),python自己使用 \ 来转义一些特殊字符,好比在字符串中加入引号的时候,为了字符串

s = 'i\'m superman'
print s
#>>> i'm superman

防止和字符串自己的引号冲突,使用 \ 来转义,通常状况下这个也不会引发什么问题,可是当你要使用 \ 来转义 \ 的时候,get

就比较混乱了,好比咱们想要输出一个 \ ,得写两个 \ ,不然会报语法错误,由于 \ 把后面的引号给转义了,必须使用 \ string

# 错误写法
# print '\'

# 正确写法
print '\\'
#>>> \

# 原生字符串
print r'\\'
#>>> \\

将 \ 转义一下使其不具有转义功能,才能够正确输出,当使用原生字符串的时候,输出显示了两个 \ ,看起来好像是写几个class

输出几个的样子,若是这样想的话,你能够试一下,看能不能输出奇数个 \。语法

先来讲一下什么是原生字符串,其实就是不进行特殊处理的字符串,所谓特殊处理,貌似就是针对转义的,原生字符串

的诞生自己就是为了解决转义的时候写了太多 \ 的问题,可是为何使用了原生字符串仍然不能只输出一个 \ 呢?其实这应

该算是一个bug,就是python的字符串不能以奇数个 \ 结尾,这样的写法会被认为是将结尾的引号进行了转义,致使语法错

误。具体能够参考http://t.cn/RfolM3H

虽然原生字符串并非很完美,但它已经能够帮咱们解决很大一部分问题了。好比当你想匹配 \ 的时候,原生字符串可

_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,虽然方便了使用,但会让人很迷惑,有利有弊吧。

# 原生
# '\$'

# 识别不了 不进行处理
# '\$'

# 正则表达式引擎接收到的
# '\$'

# 正则表达式引擎进行转义处理
# '$'

  下面举几个例子看一下

# 匹配 \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]
#>>> []
相关文章
相关标签/搜索