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

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

python的正则表达式中需要转义的元字符有以下几个:

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

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的字符串不能以奇数个 \ 结尾,这样的写法会被认为是将结尾的引号进行了转义,导致语法错

误。具体可以参考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]
#>>> []

python正则表达式转义注意事项的更多相关文章

  1. 第11.15节 Python正则表达式转义符定义的特殊序列

    一. 引言 在前面<第11.13节 Python正则表达式的转义符"\"功能介绍>介绍了正则表达式转义符'\',只不过当时作为转义符主要是用于在正则表达式中表示元字符自 ...

  2. Python正则表达式\W+和\W*匹配过程的深入分析

    在学习re.split函数的处理过程中,发现执行如下语句及返回与老猿预想的不一致: >>> re.split('\W*','Hello,world') ['', 'H', 'e', ...

  3. 第11.14节 正则表达式转义符和Python转义符相同引发问题的解决办法

    正则表达式使用反斜杠('\')来把特殊字符转义成普通字符(为了方便称为"正则表达式转义"),而反斜杠在普通的 Python 字符串里也是转义符(称为"字符串转义" ...

  4. 第11.13节 Python正则表达式的转义符”\”功能介绍

    为了支持特殊元字符在特定场景下能表示自身而不会被当成元字符进行匹配出来,可以通过字符集或转义符表示方法来表示,字符集表示方法前面在<第11.4节 Python正则表达式搜索字符集匹配功能及元字符 ...

  5. Python 正则表达式入门(中级篇)

    Python 正则表达式入门(中级篇) 初级篇链接:http://www.cnblogs.com/chuxiuhong/p/5885073.html 上一篇我们说在这一篇里,我们会介绍子表达式,向前向 ...

  6. Python 正则表达式入门(初级篇)

    Python 正则表达式入门(初级篇) 本文主要为没有使用正则表达式经验的新手入门所写. 转载请写明出处 引子 首先说 正则表达式是什么? 正则表达式,又称正规表示式.正规表示法.正规表达式.规则表达 ...

  7. 比较详细Python正则表达式操作指南(re使用)

    比较详细Python正则表达式操作指南(re使用) Python 自1.5版本起增加了re 模块,它提供 Perl 风格的正则表达式模式.Python 1.5之前版本则是通过 regex 模块提供 E ...

  8. Python正则表达式学习摘要及资料

    摘要 在正则表达式中,如果直接给出字符,就是精确匹配. {m,n}? 对于前一个字符重复 m 到 n 次,并且取尽可能少的情况 在字符串'aaaaaa'中,a{2,4} 会匹配 4 个 a,但 a{2 ...

  9. Python 正则表达式-OK

    Python正则表达式入门 一. 正则表达式基础 1.1. 简单介绍 正则表达式并不是Python的一部分. 正则表达式是用于处理字符串的强大工具, 拥有自己独特的语法以及一个独立的处理引擎, 效率上 ...

随机推荐

  1. 【338】Pandas.DataFrame

    Ref: Pandas Tutorial: DataFrames in Python Ref: pandas.DataFrame Ref: Pandas:DataFrame对象的基础操作 Ref: C ...

  2. 迷你MVVM框架 avalonjs 学习教程21、双向绑定链

    avalon的双向绑定机制,是通过一条依赖链实现.此依赖链最底层是监控属性.监控数组,中层是计算属性.监控函数,再上点是求值函数,最上层是视图刷新函数. 所谓计算属性,监控属性,监控函数属性,我们改变 ...

  3. 简单AOP

    代码如下 //使用说明 //1,新加接口与类 //2,新加类并实现ICallHandler类: ExecuteHandler //3,新建特性并实现HandlerAttribute和重写其中的Crea ...

  4. 疯狂JAVA——第六章 面向对象(下)

    6.1包装类 java为了照顾程序员的传统习惯,所以提供了八种基本数据类型.但也带来不方便,例如所有引用类型都继承自Object类,都可当做Object类型变量使用.但基本数据类型的变量就不可以.如果 ...

  5. jsp 不显示换行 Eclipse复制一行快捷键

    jsp通过out.println();不能换行.html中需要标签<br/>才可以 Eclipse 复制整行代码移动:Ctrl+Alt+↑/↓.但是跟系统屏幕上下切换冲突,可以选择,在电脑 ...

  6. Windows下搭建appium(Android版)

    1.安装node.js 说明:安装node.js是为了可以使用它的npm,可以用npm install很方便的安装它包含的包,appium server使用node.js编写的 下载地址:https: ...

  7. ECMAScript5之JSON对象属性的遍历顺序

    测试浏览器 Chrome.Safari 一 键可以用parseInt解析成整数的,按数值升序顺序. var intObj = { '3.3' : 3.3, '2' : 222, '1' :111 } ...

  8. iOS - 上架的APP 生成二维码下载

    1.首先打开苹果App Store商店进入到里面,找到需要打开链接地址的应用程序,例如:百度. 2. 在App Store商店里面先点击一下应用程序图标,再按一下…分享按钮. 3. 接着选择分享APP ...

  9. [leetcode]131. Palindrome Partitioning字符串分割成回文子串

    Given a string s, partition s such that every substring of the partition is a palindrome. Return all ...

  10. struts框架总结

    1.struts2框架开发的过程:先导包,再写配置(写struts.xml配置,还有在web.xml中进行过滤器的配置,过滤器的配置一定不能少) 2.struts框架是前端web层的框架.主要的特点: ...