注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

@fc_lamp

关注Web应用解决方案MySql/PHP/Python一盏名为"飞川"的灯~

 
 
 

日志

 
 

正则表达式匹配反斜线(杠)问题(为什么要多一个反斜杠)  

2011-05-11 12:58:00|  分类: Web技术-正则表达 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

用过正则表达式的人都知道,正则表达式中有一类叫做“元字符(meta-character)”的特殊符号,

它们并不匹配自身对应的字符,而具有其他的含义。如下表所示(常用):

元字符                                                                                             说明

\                                                          反斜线用来表示转义序列,或去掉元字符的转义。序列 '\\' 匹配 "\" 而 "\(" 则匹配 "("。

^                                                  匹配整个字符串的起始位置,或者行的起始位置,如果在字符组内部,则表示排除型(negative)字符组

$                                                                    匹配整个字符串的结束位置,或者行的结束位置

()                                                                            分组,提供反向引用(gourp1) \1或多选分支

*+?                                                                               量词,限定之前元素出现的次数

.                                                                  默认情况下匹配换行符之外的任意字符,在多行模式下可以匹配换行符

[                                                                                                  字符组的起始符号

{                                                                                                重现限定符的开始

|                                                              划分多选分支(括号没有出现时,可以想象括号出现在整个表达式最外层)

\b \B                                                                           匹配一个单词边界     \B非单词边界

\s \S                                                                               匹配任何空白字符    \S 非空白字符

\d \D                                                                                       匹配一个数字字符    \D 非数字字符

\w \W                                                                      匹配包括下划线的任何单词字符    \W 任何非单词字符


你或许注意到了,这些元字符并不是“对称”出现的,比如与开方括号 [ 对应的闭方括号 ],与开花括号 { 对应的闭花括号 } ,

这两个字符是否元字符,需要依据具体正则表达式的情况确定,我们以闭方括号]的情况为例(}的情况与此类似):如果之前能找到与

之对应的元字符开方括号[,则]作为元字符出现,否则,作为普通字符出现。

 

例如:

PHP代码

$str = 'ksfsj\kfj[中国人]skjsj[abc]fsjfks[def]fsdfsl5512[kfjf';

$patt = '/\[.*?]/';#闭方括号]就不需要再转义了

preg_match ( $patt, $str, $m );

var_dump ( $m );


 

Python代码:

import re

str = "ksfsj\kfj[中国人]skjsj[abc]fsjfks[def]fsdfsl5512[kfjf"

str = unicode(str,'utf-8')#处理编码问题(python3版本不存在这个问题)

patt = '\[.*?]'

m = re.search(patt,str)

print(m.group(0))


 

以上代码都能很好的运行。OK,让我们转移一下话题,我们知道一般语言中都有需要特殊转义的

字符常量,它们都是以以反斜线"\"开头,后跟一个或几个字符,如下:

转义字符              转义字符的意义

 \n                              回车换行

 

 \t                        横向跳到下一制表位置

 

 \b                           退格

 

 \\                           反斜线符"\"

 

 \'                             单引号符

 

 \xhh                  1~2位十六进制数所代表的字符

等等

那么我们再来看看上面代码中的patt变量的值是一个字符串,而当中的"\["在编程语言中

是一个不能识别的转义字符常量(转义序列),正确的写法应该是:“\\[”即转义第二个反斜线,

形成字符串概念上的 "\[",然后再作为正则表达概念上的"\["(非元字符)。

 

那么为什么在php与python里没有报错呢?

实际上:在php,python中如果一个转义序列不能识别,会直接原样保存到字符串中。

也就是说,Python遇到无法识别字符串中的\[,不会报错,而是将它原样“转交”给字符串。

即把"\["作为正则表意义上的转义序(因为我们知"["是一个元字符,那么非元字符就是"\[")

 

有了以上说明,就不难理解为什么正则表达式的转义序列在正则表达式中要写两个反斜线了,

比如 \+ 要写成 \\+ 。

 

我们再来看看 转义"\"的问题。

 

PHP代码

$str = 'ksfsj\kfj[中国人]skjsj[abc]fs';

$patt = '/\\\\/';

preg_match ( $patt, $str, $m );

var_dump ( $m );

 

这里为什么是四个反斜线,原因在于:我们知道在正则概念上转义反斜线的写法为:"\\" 这个在正则表式下是能匹配出\ 即 /\/,这是正则表达式引擎拿到的模式,但你也注意到了匹配出的\ 会转义后面的分隔符即:\/ ,所以我还需要一个反斜线来转义这个\ 。这样四个反斜线可理解为:前两个"生成"的\ 转义后两个"生成"的反斜杠。

不过,这一问题在python里有另外一种处理方式,使用r参数,即r"\\"表示。同样,匹配一个数字的"\\d"可以写成r"\d"。

Python代码

import re

str = "ksfsj\kfjsf"

m = re.search('\\\\',str) #不使用r

m = re.search(r'\\',str) #使用r

print(m.group(0))

正如你看到的在Python中可以使用r'\\' 来直接表示正则模式下的 \\。

我们再来看一个字符串"\section ok come 中要坷枯地无可厚非",我要匹配出 \section来。如何做?我们来看这个符串,里有"\s...."。恩,也许你记起来了,\s在正则概念上表示任何空白字符,所以你得转义s前面的\,即 \\s。这样就得到一个普通的无含义的字符“\s”了。

 

PHP代码

$s = '\section ok come 中要坷枯地无可厚非';

preg_match('/\\\\section/',$s,$m);

var_dump($m);


Python代码

import re

s = '\section ok come 中要坷枯地无可厚非'

rs = re.match(r'\\section',s)#或者 rs = re.match('\\\\section',s)

print(rs.group(0))


所以最好通用写法都写成 \\x (x指需要正则转义的字符)

参考文章:

http://www.infoq.com/cn/news/2011/01/regular-expressions-1

http://www.cnblogs.com/huxi/archive/2010/07/04/1771073.html


PHP中(转义序列(反斜线) )的解释:

http://us3.php.net/manual/zh/regexp.reference.escape.php


另外 Python Unicode 问题参看:

http://woodpecker.org.cn/diveintopython3/strings.html#one-ring-to-rule-them-all

http://blog.csdn.net/tingsking18/archive/2009/04/03/4033645.aspx


  评论这张
 
阅读(2165)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017