re模块:正则表达式

re模块:正则表达式

正则表达式主要用到的是re模块

模块方法

re模块在使用的时候要注意,有的函数使用后返回的是一个对象,比如re.search(),re.match(),这些函数都是使用group()函数来返回结果,而有的函数在使用后直接返回结果,比如`re.split(),re.findall`

result = re.search()

在字符串中搜索, 注意,搜索的字符串必须写成原始字符串,只能搜索出第一个匹配

>>> import re
>>> re.search(r'hello','hello,world')
<_sre.SRE_Match object; span=(0, 5), match='hello'>

 

result.group()

re.search()方法返回的是一个匹配对象而不是字符串,如果要将匹配对象转换成字符串,就要用到这个方法

>>> result = re.search(r'hello','hello,world')
>>> result.group()
'hello'
>>> result
<_sre.SRE_Match object; span=(0, 5), match='hello'>

如果正则表达式里面的内容存在子组,那么子组会将里面的内容进行捕获通过在group里面设置序号,可以提取到对应捕获的字符串

>>> result = re.search(r'(\w+)(\w+)','hello,world hello')
>>> result.group()
'hello'
>>> result.group(1)
'hell'
>>> result.group(2)
'o'

 

result.start() 返回匹配的开始的位置

result.end() 返回匹配的结束的位置

result.span() 返回匹配的我]范围

>>> result.start()
0
>>> result.end()
5
>>> result.span()
(0, 5)

 

re.match(pattern,string,flag = 0)

检查string是否存在一个和pattern匹配的前缀,也就是从string开头开始就和patterny匹配成功是返回相应的match对象,否则返回None

>>> result = re.match(r'how','hello how are you')
>>> result
>>> result = re.match(r'how','how are you')
>>> result
<_sre.SRE_Match object; span=(0, 3), match='how'>
>>> result.group()
'how'

 

re.split(pattern,string,maxsplit=0,flag=0)

函数返回分割得到的字符串的列表

>>> result = re.split(r'how','hello how are you')
>>> result
['hello ', ' are you']

 

re.findall()

匹配所有找到的字符串,把他们打包成列表返回

>>> result = re.findall(r'how','hello how are you how ')
>>> result
['how', 'how']

 

re.compile()

编译正则表达式(如果你需要重复的使用某个正则表达式,则需要将该正则表达式编译成模式对象)

>>> p = re.compile(r'[A-Z]')
>>> p.search('ksdjfhaskKJHKJHJjhJhhj')
<_sre.SRE_Match object; span=(9, 10), match='K'>
>>> result = p.search('ksdjfhaskKJHKJHJjhJhhj')
>>> result.group()
'K'
>>> result = p.match('AlksdjSkF')
>>> result.group()
'A'
>>> p.findall('lskdFlskdIljalsdkH')
['F', 'I', 'H']
>>> p.split('lskdFlskdIljalsdkH')
['lskd', 'lskd', 'ljalsdk', '']

 

正则表达式表示方法

正则表达式是通过一个元字符构成一个模式,然后通过这个模式来匹配出很多字符串中符合这个模式的字符串

. ^ $ | 元字符

. 表示除换行符以外的任意字符
​
^ 表示只匹配字符串开头的位置
​
$ 表示只匹配字符串结尾的位置
​
| 表示逻辑或
​
>>> import re
​
>>> ret1=re.findall('李.','李爽\nalex\n李四\negon\nalvin\n李二') 
​
>>> ret2=re.findall('^李.','李爽\nalex\n李四\negon\nalvin\n李二')
​
>>> ret3=re.findall('李.$','李爽\nalex\n李四\negon\nalvin\n李二')
​
>>> ret1
​
['李爽', '李四', '李二']
​
>>> ret2
​
['李爽']
​
>>> ret3
​
['李二']

*+?{} 表示重复

*              零到无穷次
​
+              一到无穷
​
?             0-1次
​
{}             指定次数

 

\ 的奥义

  1. 将元字符去除其特殊功能

  2. 将一些普通符号转换成特殊意义的符号

    匹配字符

    \A:匹配输入字符串的开始位置,^用法一样
    \Z:匹配输入字符串的结束位置,用法和$一样
    \b :匹配一个单词边界,单词被定义为unidcode的字母数字或下横线字符
    \d  匹配任何十进制数;      它相当于类 [0-9]\D  匹配任何非数字字符;    它相当于类 [^0-9]\s  匹配任何空白字符;      它相当于类 [ \t\n\r\f\v]\S  匹配任何非空白字符;    它相当于类 [^ \t\n\r\f\v]\w  匹配任何字母数字字符;   它相当于类 [a-zA-Z0-9_]\W  匹配任何非字母数字字符; 它相当于类 [^a-zA-Z0-9_]
    \b  匹配一个特殊字符边界,比如空格 &,#等

    匹配数字

    如果 \ 后面的数字为(1~99),表示引用序号对应的子组所匹配的字符串
    ​
    如果 \ 后面的数字为零或者三位数字(八进制),表示这个八进制对应ASC码的字符

    转义

    转义符号:正则表达式支持大部分Python字符串的转义符号:
    \a,\b,\f,\n,\r,\t,\u,\U,\v,\x,\\
  3. 如果在方括号里面不会失去其特殊含义

  4. 如果想要表示\,则在前面再加一个\,应该这样表示\\

()的奥义:分组

使用小括号指定一个子表达式后,匹配这个子表达式的文本(也就是此分组捕获的内容)可以在表达式或其它程序中作进一步的处理。默认情况下,每个分组会自动拥有一个组号,规则是:从左向右,以分组的左括号为标志,第一个出现的分组的组号为1,第二个为2,以此类推。

使用小括号指定子表达式匹配时是按照所有的模式匹配,但是返回显示的时候只显示括号内匹配的内容

(?:…)非捕获组,即该子组匹配的字符串无法从后边获取

(?P<name>.....) 给此分组命名

>>> result = re.search(r'(\w+)(\w+)','hello,world hello')
>>> result.group()
'hello'
>>> result.group(1)
'hell'
>>> result.group(2)
'o'

[…]

生成一个字符类,也就是一个集合,里面包含的所有字符都会失去其特殊性除了几个特殊的字符,这个字符类

这个字符类只会选择括号里面所有字符的一个进行匹配

如果直接是一个点,则会匹配除了换行符以外的所有字符,反斜杠加点则匹配点本身,而方括号里面的点会失去其特殊性,也会匹配点本身

-  如果出现在字符串中间则表示字符范围描述,如果出现在首位则表示普通字符
​
>>> re.findall(r'[a-z]','welkj1234sdkjfHIK')
['w', 'e', 'l', 'k', 'j', 's', 'd', 'k', 'j', 'f']
​
\  特殊字符中仅仅反斜杠保持原来的特殊意义,其他的字符都作为普通字符匹配
​
 ^ 如果出现在方括号中标志除了类里面的字符,其他的都匹配,脱字符只能放在前面,如果放后面则表示匹配脱字符本身

 

非贪婪模式:

一般情况下,* , + 和 ? 的匹配模式是贪婪模式(即会尽可能多的匹配符合规则的字符串) *? ,+? 和 ?? 会表示启用对应的非贪婪模式

 

正则表达式常用组合(如果m能匹配字符串s,n能匹配字符串t,):

  1. 正则表达式里的普通字符只与该字符本身匹配

  2. mn:匹配字符串拼接s+t

  3. m|n:既能匹配s,也能匹配t

  4. m*:能匹配空串、s、s+s、s+s+s等

典型例题

由于字符范围比较特殊,比如月份,需要考虑的很多,比如前面一位取0时,后面一位取0-9,而当前面一位取1时,后面一位只能取012,所以应该分情况考虑

# 年份
s4 = '1990-07-12lskd2016-09-35jfls1989-12-30laksdjf2931989-13-14f8478-32098-34-34-5-123'
​
p4 = re.compile(r'[12]\d{3}-(?:0\d|1[012])-(?:[012]\d|3[01])')
print(p4.findall(s4))
​
['1990-07-12', '1989-12-30']

 

posted @ 2017-06-26 20:26  戴维德  阅读(159)  评论(0编辑  收藏  举报