python中使用正则表达式

时间:2022-05-23 03:49:01

正则表达式
元字符:. ^ $ * + ? {} [] \ | ()
第一部分:
1.[]
常用来指定一个字符集,用于匹配其中的一个字符;^,$元字符在里面不起作用,但是+-*等符号在[]中还是有特殊含义的,可以参见split函数使用部分。
>>> r = r'm[abc]n'
>>> re.findall(r,'manddmcnkkkmdn')
['man', 'mcn']
>>> r =r'm[^abc]n'
>>> re.findall(r,'manddmcnkkkmdn')
['mdn']
这里m[^abc]n'表示出了man,mbn,mcn之外的m开头n结尾的三位字符;

2. ^ 在字符串中作为首字母用于匹配行首,'^abc'表示以abc开头的字符串;
>>> r =r'^abc'
>>> re.findall(r,'abdddd')
[]
>>> re.findall(r,'abcccc')
['abc']
>>> re.findall(r,'bcabc')
[]
如果用在字符串的非首字母中不知道什么含义(不确定),如下实践结果:
>>> r =r'a^b'
>>> re.findall(r,'a^b')
[]
>>> re.findall(r,'a')
[]
>>> re.findall(r,'ac')
[]

如果用在[]中开头字母表示非,如上面[^abc]表示非a,非b,非c的其他情况;
如果用在[]非首字母就表示普通的字符,如下:
>>> r = r't[a^]'
>>> re.findall(r,'ta')
['ta']
>>> re.findall(r,'t^')
['t^']

3. $ 字符串末尾用于匹配行尾,'abc$'表示以abc结尾的字符串,但是在如果$用在了[]中就表示普通的字符:
>>> r = r'a[b$]'
>>> re.findall(r,'ab')
['ab']
>>> re.findall(r,'a$')
['a$']
>>> r = r'ab$'
>>> re.findall(r,'ab')
['ab']
>>> re.findall(r,'abb')
[]
>>> re.findall(r,'cab')
['ab']
>>> re.findall(r,'ab$')
[]

第二部分:
1. 把一个元字符转换成普通的字符时候可以用反斜杠"\";
例如:"^ab"表示以ab开头的字符串;"\^ab"表示字符串"^ab",这里的^就是普通字符无特殊含义;
>>> import re
>>> r =r"^ab"
>>> re.findall(r,"abc")
['ab']
>>> re.findall(r,"bcd")
[]
>>> r=r"\^ab"
>>> re.findall(r,"^abcd ab")
['^ab']
>>>

2. 反斜杠除了用于取消元字符的意义外,反斜杠后面还可以添加不同的字符以表示不同的特殊意义:
\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_]

3. *表示它前面一个字符出现0到多次,例如下面b字符没有出现也能匹配到;
>>> r = r'ab*'
>>> re.findall(r,'a')
['a']
>>> re.findall(r,'ab')
['ab']
>>> re.findall(r,'abb')
['abb']
>>> re.findall(r,'abbbbbb')
['abbbbbb']

4. + 表示它前面的字符至少出现一次,例如下面b字符没有出现时候匹配不到;
>>> r =r'ab+'
>>> re.findall(r,'a')
[]
>>> re.findall(r,'ab')
['ab']
>>> re.findall(r,'abbb')
['abbb']

5. ? 表示它前面的字符出现一次或者0次,一般用于连接可有可无的符号。例如电话号码中”-“出现可以不出现也可以就可以用"-?"来表示;

6. 贪婪模式(最大匹配)
>>> r = r'ab+'
>>> re.findall(r,'abbbbbbbb')
['abbbbbbbb']

7. 非贪婪模式(最小匹配)
>>> r = r'ab+?'
>>> re.findall(r,'abbbbbbbbb')
['ab']

8.{m} 前面一个字符m次
{m,n} 表示前面一个字符至少出现m次,最多出现n次,如'a{1,3}'表示a字符出现1到3次;
例如:
>>> r = r'a{1,3}'
>>> re.findall(r,'a')
['a']
>>> re.findall(r,'b')
[]
>>> re.findall(r,'aaa')
['aaa']
>>> re.findall(r,'aaaa')
['aaa', 'a']

9 {0,}等同于*
{1,}等同于+
{0,1}等同于?

正则表达式常用函数:
1. 编译正则表达式以提高执行效率re.compile(表达式,匹配字符,[标记位])
>>> r = r'\d{3,4}-?\d{8}'
>>> tel = re.compile(r)
>>> tel.findall('025-88886400')
['025-88886400']
>>> re.findall(tel,'025-88886400')
['025-88886400']
>>>
>>> r = r'abc'
>>> s = re.compile(r)
>>> s.findall('Abc')
[]
>>> s =re.compile(r,re.I)
>>> s.findall('Abc')
['Abc']
>>> re.findall(s,'Abc')
['Abc']
>>>

注意:定义正则表达式加r跟不加r有什么区别?

2. match,开头匹配上才能匹配返回
>>> s =re.compile(r,re.I)
>>> s.findall('Abc')
['Abc']
>>> re.findall(s,'Abc')
['Abc']
>>>

3. search,不管什么位置匹配上都返回
>>> re.search(r,'abc hi')
<_sre.SRE_Match object at 0x00BFF800>
>>> re.search(r,'hi abc')
<_sre.SRE_Match object at 0x00BFF870>
>>>

注: match跟search如果没有匹配到的话,返回None,如果成功匹配则返回一个'MatchObject'实例,如上。
查看MatchObject的数据方法:
group返回被匹配的字串;
start返回匹配开始的位置;
end返回匹配结束的位置;
span返回一个元组,包含匹配开始,结束的位置。
>>> r = r'abc'
>>> re.search(r,'hi abc hi abc no abc')
<_sre.SRE_Match object at 0x00BFF838>
>>> x = re.search(r,'hi abc hi abc no abc')
>>> print(x)
<_sre.SRE_Match object at 0x00BFF800>
>>> x.group()
'abc'
>>> x.group(0)
'abc'
>>> x.group(1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: no such group
>>> x.start()
3
>>> x.end()
6
>>> x.span()
(3, 6)

4. findall 找到满足规则的所有字符串,作为一个列表返回;

5. finditer 找到满足规则的所有字符串,作为一个迭代器返回;

6. sub 根据正则表达式做字符串替换
>>> r = r'a..t'
>>> re.sub(r,'hi','abttt acvt')
'hit hi'
>>> re.subn(r,'hi','abttt acvt')
('hit hi', 2)

7. subn 返回结果中多了一个值,替换了多少次。

8. split 对字符串进行切割,[]中使用+*等元字符时候需要用反斜杠。
>>> s = '124+235-566*888'
>>> re.split(r'[\-\+\*]',s)
['124', '235', '566', '888']

正则表达式内置属性:
1. 编译标志位
I表示不区分大小写;
S表示匹配换行在内的所有字符,例如:
>>> r = r'abc.zdr'
>>> re.findall(r,'abcczdr')
['abcczdr']
>>> re.findall(r,'abc.zdr')
['abc.zdr']
>>> re.findall(r,'abc\nzdr')
[]
>>> re.findall(r,'abc\nzdr',re.S)
['abc\nzdr']
M表示多行匹配,一般用于从文件中读取数据,例如:
>>> s = """
... hi yahoo
... yahoo hi
... hi sina
... sina hi
... """
>>> r = r'^hi'
>>> re.findall(r,s)
[]
>>> s
'\nhi yahoo\nyahoo hi\nhi sina\nsina hi\n'
>>> re.findall(r,s,re.M)
['hi', 'hi']
X表示定义的正则表达式包含多行的时候,如果使用它就需要加上X属性,例如:
>>> tel =r"""
... \d{3,4}
... -?
... \d{8}
... """
>>> tel
'\n\\d{3,4}\n-?\n\\d{8}\n'
>>> re.findall(tel,'025-12345678')
[]
>>> re.findall(tel,'025-12345678',re.M)
[]
>>> re.findall(tel,'025-12345678',re.X)
['025-12345678']

正则表达式中分组:(|),当有分组的时候,匹配查询的结果只有分组的字符,利用这个特性一般会有很多用途;
>>> email = r'\w{3,6}@\w+(\.com|\.cn)'
>>> re.match(email,'ggg@aaa.com')
<_sre.SRE_Match object at 0x00C575A0>
>>> re.match(email,'ggg@aaa.cn')
<_sre.SRE_Match object at 0x00C57560>
>>> re.match(email,'ggg@aaa.org')
>>>
>>> re.findall(email,'ggg@aaa.com')
['.com']