标签:制表符 还需 关系 其他 div 程序编写 name 学习 cape
正则表达式(regular expression)这玩意儿多nb就不用说了,python用re模块来支持正则
首先是一些正则表达式的概念
1. 通配符 .
2. 多字符选择 [...]
[abc]表示匹配abc中任何一个,而比如[A-Za-z]这种表示也是许可的。此外还有[^...]表示除了...外的字符
3. 选择符 ...|... 二选一
4. 对特殊字符的转义
如"python\.org" 可以匹配 "python.org" 而不匹配"pythonAorg"
5. 子模式
对一部分字符串加小括号以进行不同于整串的操作,比如"P(ython|erl)"同时匹配 "Python"和"Perl"
6. 可选项
(...)? 表示不管带不带这个子模式都会匹配,只识别问号前一个的字符or子模式
7. 可重复(也都是识别标识符前一个的字符or子模式)
(...)* 重复任意次(也可不重复)
(...)+ 重复至少一次
(...){m[,n]} 重复m(到n)次
8. 字符串开头和结尾
‘^...‘ 表示从开头开始匹配,注意区别这个和反向匹配多字符(那个有中括号)
‘...$‘ 表示只在结尾匹配
9. 一些预定义字符
\d 相当于 [0-9] 所有数字字符
\D 相当于 [^0-9] 所有非数字字符
\s 相当于 [\t\r\n...] 所有空白字符
\S 相当于 所有非空白字符
\w 相当于 [a-zA-Z0-9_] 所有在单词中可能用到的字符(大小写字母,数字,下划线)
\W 相当于 [^\w] 所有非单词书写字符
■ re模块的一些方法
compile(pattern)
根据正则表达式pattern返回一个相应的模式对象,用这个对象可以调用其他所有re模块下的方法使得使用起来更加方便,比如原来要re.search(pattern,string),现在只要pattern.search(string)
search(pattern,string) 或 pattern.search(string) 下同,不再复述
从字符串中寻找相关pattern,找到则返回一个object(可以视为True),没找到则返回None(可以视为False)
match(pattern,string)
从字符串开头开始匹配,若成功匹配,返回object,否则返回None //如果是match的pattern里有...$这种匹配字符串尾的怎么办。。这种矛盾怎么解决,该听谁的?
split(pattern,string)
用string中任何与pattern匹配的部分作为分隔符分隔string,返回的是一个列表
findall(pattern,string)
找出string中所有和pattern匹配的部分,并将其组成一个列表返回
sub(pattern,replace,string)
将string中所有pattern匹配的部分用replace串替换,string本身值不变,sub方法返回更改的字符串
replace中可以带 \g<1>,\g<2>..等参数,用来表示pattern中的相应的group。相当于是把原来字符串里匹配到一些group的内容动态地提取出来并把 其整合到replace里面
如:
originStr = "Hello, Frank" pattern = "Hello, (\w+)" replace = "Mein Name ist \g<1>" replacedStr = re.sub(pattern,replace,originStr) #得到relacedStr是"Mein Name ist Frank"
escape(string)
用于把stirng中所有实义字符(在正则表达式引擎的层面上)反转义为带‘\‘的形式
比如escape(‘www.baidu.com‘) ==> ‘www\.baidu\.com‘ 这样把这个字符串去当pattern时就不会有把"."当成是通配符了
■ 匹配对象和组
之前提到了,像search这种方法会返回一个object,这个object是个MatchedObject,即匹配对象。那么这个对象中有哪些信息呢
首先要提一下group的概念。在一个pattern中,常会出现小括号括起来的子模式,根据这些子模式和总模式的关系,可以将pattern以及最终匹配出来的字符串分成若干group
比如pattern这样的话:"I (am (Kazuya) Takanashi). This (is) a test" 这里面有四个group
0: 整个字符串
1:am Kazuya Takanashi
2:Kazuya
3:is
看是第几组只要看左边出现了几个左括号
对于匹配完成后得到的MatchedObject,它有:
m.group(组号) 获取相应组的内容,若不写组号默认为0,下同
m.start(组号) 获取相应组在原串中的起始位置
m.end(组号) 获取结束位置
m.span(组号) 以元组的形式返回相应组的开始和结束位置
■ 正则解析过程浅析
这是我自己YY出来的,不知道是否准确。
正则表达式的转义也很复杂,其整个过程应该是这样的:
程序编写时的字符串 ==(第一次转义)==> print时出现的字符 ==(第二次转义,正则引擎的转义)=> 正则对象
要匹配一个逻辑上的反斜杠,即匹配的字符串要写"\\"(不能写r"\",这可能是整个python唯一不能用rXX来表示的字符串了),pattern要写 "\\\\" 或 r"\\" (对于那些反斜杠和它之后跟的东西并不组成一个转义字符的情况,写不写r都一样,因为python看到反斜杠会自动把它escape掉,比如s="a\.b"在内存中自动是"a\\.b"。而对于反斜杠和它之后那个字符组合起来可能引起歧义的情况就有差别了,比如s="a\tb"和k=r"a\tb",内存中两者分别是"a\tb"和"a\\tb",print出来后前者有个制表符空格,后者则是a\tb)
可以看到,re.search("\\\\","\\")是有返回object的,说明匹配成功。这就表明其实这个方法不是直接拿pattern在内存中的形式(四条杠)和目标在内存中的形式(两条杠)比较,而是拿到前者之后先对它做一个属于系统层面的转义,再对它做一个专属于正则的转义,之后再拿去和经过正则转义的目标对比
#苦想了很久,姑且算找到一个可以自圆其说的说法。。但是具体是不是这样,还有待检验。关于这个转义来转义去的问题,还需要进一步对python字符串和正则本身机制的了解学习
■ 关于贪婪和懒惰
重复匹配符如*,+这些默认都是贪婪的。
所谓贪婪就是说当可以匹配多种可能时,匹配最长的。比如:
pattern = "<.*>" 而 string = "<a>bcd>ef>"时,re会匹配到"<a>bcd>ef>"而不是"<a>"或"<a>bcd>"
向重复匹配符后加上?可以使其进行懒惰匹配,也就是匹配最短的,如上例中匹配到的应该是"<a>"而不是"<a>bcd>ef>"或"<a>bcd>"。(注意区分这个和可选项匹配的问号:(...)?表示可有可无的子模式或字符)
标签:制表符 还需 关系 其他 div 程序编写 name 学习 cape
原文地址:http://www.cnblogs.com/franknihao/p/6534735.html