正则表达式

正则表达式
动机 : 
1.处理文本已经成为计算机主要工作内容
2.根据文本的内容进行固定的筛选匹配是文本处理中常用的工作之一
3.为了快速方便的解决上述问题,正则表达式应运而生,并且主键发展为一个单独的技术。可以被众多编程语言使用。

定义 :即高级的文本模式匹配,提供了搜索和替代等功能。本质是 由一些字符和特殊符号组成的字符串。这个字符串描述了这些字符和字符的某种重复方式,按照这种方式可以匹配一个有相似特征的符合规则的字符集合。


目标 :
1.理解什么是正则表达式及正则表达式的用途
2.能够掌握正则表达式的规则和用法
3.能够使用python re模块进行基于正则表达式的文本操作


特点和用途


* 使用编程进行文本的检索和修改
* 正则表达式支持语言众多,方便使用
* 正则表达式可以匹配一系列字符串而不是某一个,匹配更多样化
* 在mongo中可以存储正则表达式,也可以使用正则表达式做查找操作
* 大量使用在爬虫中用来处理html文本匹配
* django,tornado 的路由匹配


正则表达式规则和用法


元字符的使用


re.findall(regex,string)
功能:在string字符串中,匹配regex正则表达式能够匹配的项,放到一个列表中返回


* 普通字符串 


元字符 :abc  
匹配规则 : 匹配字符串的值
匹配示例 :abc 


In [3]: re.findall('abc','abcdeabc')
Out[3]: ['abc', 'abc']





* 使用“或”进行多个匹配


元字符: re1 | re2
匹配规则:既能匹配正则表达式re1所表达内容,也能匹配           re2所表达内容
匹配示例:ab | bc  --》  ab   bc
In [5]: re.findall('ab|de','abcdeabc')
Out[5]: ['ab', 'de', 'ab']

* 点号  "."


元字符: .
匹配规则:匹配任意一个字符
匹配示例:f.o   ——》  foo   fao   f@o  
In [6]: re.findall('f.o','foo,f@oabfabo')
Out[6]: ['foo', 'f@o']


* 匹配开头子串


元字符:  ^   
匹配规则:匹配一个字符串的开头位置
匹配示例:^From  匹配以 From 开头的字符串起始部分
In [9]: re.findall('^From','From China')
Out[9]: ['From']



In [10]: re.findall('^From','I come From China')
Out[10]: []


* 字符集合不匹配


元字符 : [^...]   ... 表示上面两项中任意内容
匹配规则: 匹配任意非中括号中的字符集
匹配示例: [^aeiou]  匹配任意一个非aeiou字符 
           [^a-z]  匹配任意一个非小写字母
In [46]: re.findall('[^a-z]','abc1j2^&d')
Out[46]: ['1', '2', '^', '&']


In [47]: re.findall('[^aeiou]','hello world')

Out[47]: ['h', 'l', 'l', ' ', 'w', 'r', 'l', 'd']


*匹配字符串的结尾
元字符 :  $ 
匹配规则 : 当一个字符串以什么结尾时使用$标记
匹配示例 : py$ -》  匹配所有以py结尾的字符串
In [17]: re.findall('py$','test.py')
Out[17]: ['py']



In [18]: re.findall('py$','python')
Out[18]: []


* 匹配任意0个或多个字符


元字符 :   *

匹配规则: 匹配前面出现的字符或正则表达式0次或者多            次
匹配示例: ab* ->   abbbbbbbb
In [23]: re.findall('.*','askjdfh89w4234')
Out[23]: ['askjdfh89w4234', '']


In [24]: re.findall('.*','askjdfh89w4234sdfhhg')
Out[24]: ['askjdfh89w4234sdfhhg', '']


In [25]: re.findall('ab*','a')
Out[25]: ['a']


In [26]: re.findall('ab*','abbbb')
Out[26]: ['abbbb']



*  匹配任意1个或多个字符


元字符 :   +

匹配规则: 匹配前面出现的字符或正则表达式1次或者多            次
匹配示例: ab+ ->   abbbbbbbb
In [28]: re.findall('ab+','abbbb')
Out[28]: ['abbbb']


In [29]: re.findall('ab+','a')
Out[29]: []


* 匹配字符 0 次或1次


元字符 :  ?
 
匹配规则:匹配前面出现的字符或正则表达式0次或1次
匹配示例: ab? --》 a  或者  ab
In [31]: re.findall('ab?','a')
Out[31]: ['a']


In [32]: re.findall('ab?','ab')
Out[32]: ['ab']



* 匹配前面的字符或re指定次数




* 匹配前面的字符或re指定次数


元字符 : {M,N}    M,N代表数字
匹配规则:匹配前面出现的字符正则表达式M 到 N次
匹配示例: ab{3,8} --》 abbb  abbbbbbbb
In [36]: re.findall('ab{3,8}','abbb')
Out[36]: ['abbb']


In [37]: re.findall('ab{3,8}','abbbbbbbbbbb')
Out[37]: ['abbbbbbbb']


* 字符集合匹配


元字符 : [abcd]
匹配规则: 匹配中括号中任意一个字符

匹配示例: b[abcd]t    ->   bat  bbt  bct  bdt
In [40]: re.findall('b[abc123]t','bat,b1tba3t')
Out[40]: ['bat', 'b1t']


In [41]: re.findall('[ab][cd]','acadbcbd')
Out[41]: ['ac', 'ad', 'bc', 'bd']



* 字符集合匹配


元字符 : [a-zA-Z0-9] [a-z] [0-9] [a-zA-Z] [3-8]
          [b-x]

匹配规则: 匹配中括号中任意一个区间内的字符
匹配示例: [a-zA-Z0-9]+  匹配任意一个由字母数字组 In [43]: re.findall('[a-zA-Z0-9]+','safd1324')
Out[43]: ['safd1324']


In [44]: re.findall('[a-zA-Z0-9]+','adf$&^%123')
Out[44]: ['adf', '123']




元字符 : {N}    N代表一个数字
匹配规则:匹配前面出现的字符或正则表达式N次
匹配示例: ab{3} --》 abbb
In [34]: re.findall('ab{3}','abbbbbb')
Out[34]: ['abbb']


In [35]: re.findall('ab{3}','abb')
Out[35]: []





* 匹配(非)数字字符


元字符 : \d  [0-9]   \D [^0-9] 
匹配规则 : \d 匹配任意一个数字字符 
           \D 匹配任意一个非数字字符

匹配示例 :\d{3}  -->  '123'
In [49]: re.findall('\d{3}','hello 1234')
Out[49]: ['123']


In [50]: re.findall('\D{3}','hello 1234')
Out[50]: ['hel', 'lo ']



* 匹配(非)字母数字字符


元字符 : \w  [a-zA-Z0-9]   \W   [^a-zA-Z0-9]
匹配规则 : \w 匹配任意一个字母或数字字符 
           \W 匹配任意一个非字母或数字字符

匹配示例 :\w{3}  -->  'a23'
In [51]: re.findall('[A-Z]\w*','Hello World')
Out[51]: ['Hello', 'World']


In [52]: re.findall('\w+-\d+','xiaoming-56')
Out[52]: ['xiaoming-56']


* 匹配(非)空字符


元字符 : \s  (空格 \n  \0  \t  \r)    \S
匹配规则 : \s 匹配任意一个空字符 
           \S 匹配任意一个非空字符

匹配示例 :hello world  -> hello world


In [58]: re.findall('hello\s+world','hello   world')
Out[58]: ['hello   world']


In [60]: re.findall('\S*','helloworld&* ask')
Out[60]: ['helloworld&*', '', 'ask', '']


In [61]: re.findall('\s','a b c\n')
Out[61]: [' ', ' ', '\n']


*匹配字符串开头和结尾 


元字符  \A  (^)  \Z ($)

匹配规则: \A 匹配字符串的开头位置
           \Z 匹配字符串的结尾位置



匹配示例: \Aabc\Z     ^abc$   - > abc


In [70]: re.findall('\Aabc\Z','abcabc')
Out[70]: []
In [66]: re.findall('\Aabc\Z','abc')
Out[66]: ['abc']
In [68]: re.findall('efg\Z','hi,abcdefg')
Out[68]: ['efg']


* 匹配(非)单词边界


元字符 : \b   \B
匹配规则 : 将非字母的部分不认为是单词部分
            将连续字母的部分认为是一个单词

匹配示例: “This is a %test%”


In [74]: re.findall(r'\btest\b','This is a %test%')
Out[74]: ['test']


In [75]: re.findall(r'\bThis\b','This is a %test%')
Out[75]: ['This']


In [76]: re.findall(r'\bis\b','This is a %test%')
Out[76]: ['is']


In [77]: re.findall(r'\Bis\b','This is a %test%')
Out[77]: ['is']


In [78]: re.findall(r'is\b','This is a %test%')
Out[78]: ['is', 'is']





元字符总结


字符 : 匹配实际字符       
匹配单个字符:  .   []   \d  \D  \w \W  \s  \S
匹配重复次数: *   +   ?  {} 
匹配开头结尾: ^  $  \A  \Z   \b  \B
其他 : |    [^ ]



raw字串和转义


r“hello world”   ->  raw字串


raw字串特点 : 不进行转义解析


“hello \n world”    -> \n表示换行 
r"hello \n world"   -> \n表示两个字符


什么时候加r


转为raw字符串是为了防止python对字符串的转义解析,所以在正则表达式本身有“\”的时候最好加上r


正则表达式的转义匹配
当匹配正则表达式内的特殊字符的时候,正则表达式本身也需要进行转义,如要匹配字符串中的 *  则正则表达式应为“\*”
特殊字符如下:
\   *  .  ?  ()  []  {}  ""  ''


匹配字符串中的*
In [86]: re.findall(r'\*','* is not \\, \\ is not ?')
Out[86]: ['*']


In [87]: re.findall('\\*','* is not \\, \\ is not ?')
Out[87]: ['*']


匹配字符串中的“\”
In [89]: re.findall('\\\\','* is not \\, \\ is not ?')
Out[89]: ['\\', '\\']


In [90]: re.findall(r'\\','* is not \\, \\ is not ?')
Out[90]: ['\\', '\\']




贪婪和非贪婪


贪婪模式 : 不做处理的情况下,正则表达式默认是贪婪模式。即 在使用 *   +  ?  {M,N} 的时候尽可能多的向后进行匹配。
e.g. 
ab*  可以匹配 a   ab  abbb... 那么当b足够多的时候它会尽可能多的去匹配


In [96]: re.findall(r'ab*','abbbbbbb')
Out[96]: ['abbbbbbb']


非贪婪模式:尽可能少的匹配复合正则条件的内容


贪婪模式 ---》 非贪婪模式 方法:后面加“?”
即 *?   +?   ??  {M,N}?



In [100]: re.findall(r'ab*?','abbbbbbb')
Out[100]: ['a']


In [101]: re.findall(r'ab+?','abbbbbbb')
Out[101]: ['ab']


In [102]: re.findall(r'ab??','abbbbbbb')
Out[102]: ['a']


In [103]: re.findall(r'ab{2,4}?','abbbbbbb')
Out[103]: ['abb']


正则表达式分组


((ab)*(cd))
正则表达式 (ab)*cd


1. 正则表达式可以分组,分组的标志即括号(),每个括号都是正则表达式的一个子组,而每个子组是整体正则表达式的一部分,同时也是一个小的正则表达式


2. 当有多个子组的时候,我们从外层向内侧分别叫第一,第二....子组。当同一层次的时候,从左向右分别计数

((ab)*(cd))

        2            3

1

3. 分组会该表* + ? {}  的重复行为,即把每个分组当做一个整体对待,进行相应的重复操作
4. 当子组能后和多个目标字符串内容进行匹配时,只返回一个内容


In [113]: re.findall(r'(ab)+cd','ababcdef')

Out[113]: ['ab']


[2]: re.findall(r'(ab)+(cd)','abababcdef')
Out[2]: [('ab', 'cd')]


 [4]: re.findall(r'(ab(abcd))','abababcdef')
Out[4]: [('ababcd', 'abcd')]


5.每个组都可以起名字,我们可以根据起的名字辨别各个组。


格式: (?P<word>hello)  
给子组(hello) 起一个名字,这个名字是 “word”
子组通过名字进行调用 (?P=word)  表示复制子组正则表达式内容

In[1]:re.findall(r'(?P<word>\b\w+\b)','hello world')

Out[2]:['hello','world']

?P<word>子组名字 调用


In [123]: re.findall(r'((?P<word>hello)\s+(?P=word))','hello hello')
Out[123]: [('hello hello', 'hello')]


********************************************
1. 匹配长度8-10位的密码,必须字母开头,数字或字母下划线组成


^[a-zA-Z][_a-zA-Z0-9]{7,9}$


2.匹配简单的身份证号


\d{17}(\d | x)






re模块


'compile'


说明 : 
1.以下七个函数是正则表达式匹配的常用函数
2.这七个函数既可以使用re直接调用,也可以使用
  re.compile() 生成的正则表达式对象来调用,其功能完全相同
3.使用re模块直接调用的时候,这些函数的第一个参数需要传入正则表达式。而使用compile对象调用的时候,因为已经确定了正则表达式,所以不需要再传入
e.g.:    re.findall(r'\w+','hello world')


         obj = re.compile(r'\w+')
obj.findall('hello world')


 findall:获取字符串中所有能够被正则表达式匹配的字串,以列表返回。如果加子组则返回每个子组中的内容


 finditer:同findall 只是返回的是一个迭代器,每次迭代取得的是一个match对象
 
matchobj.group()  可以获取匹配的具体内容


split : 将一个字符串,按照正则表达式的匹配内容进行分割,得到分割后的列表

In [2]: re.split(r'\s','hello world ni hao jane')

Out[2]: ['hello', 'world', 'ni', 'hao', 'jane']


sub(restring,string,max = 0)
将正则表达式匹配的string字符串的内容替换为restring
max如果不写则表示全部替换,如果赋值则表示最多替换max处

In [6]: print(re.sub(r'[A-Z]',"*****",'Hello Woeld Sudhh ijijadih ',2))

*****ello *****oeld Sudhh ijijadih 



subn 同sub 只不过返回值多一个实际替换的值

n [8]: print(re.subn(r'[A-Z]',"*****",'Hello woeld sudhh ijijadih ',2))

('*****ello woeld sudhh ijijadih ', 1) #实际替换 1个



'match':匹配正则表达式对应的内容但是 能 一项

初始位置 匹配到  返回 一项,匹配不到  返回None


'search', 所匹配的 内容 从 全局匹配 ,不限定开始位置,也只返回一个



  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值