python re
re的常用函数
re.search()和re.match()
re.search()和re.match()一样,参数都是(pattern, str),但区别是re.match()只从头开始匹配,re.search()搜索整个字符串。
但我都能搜索整个字符串了,我还用match干什么呢。也许你会说效率云云,也有一定道理,但都用python代码了我还那么关心效率干什么呢。总之我是只用search的。
import re
pattern = 'dog'
m1 = re.match(pattern, "I'm not dog")
m2 = re.search(pattern, "I'm not dog")
print(m1)
print(m2)
result:
None
<re.Match object; span=(8, 11), match='dog'>
结果为match没有匹配上,search成功找到了
另外,如果不指定,search只会寻找第一个符合要求的内容
import re
pattern = 'dog'
m = re.search(pattern, "I'm not black dog but white dog")
print(m)
result:
<re.Match object; span=(14, 17), match='dog'>
可以看到search的结果还需要进一步加工,如果需要知道位置和内容,使用span和group即可
import re
pattern = 'dog'
m = re.search(pattern, "I'm not black dog but white dog")
print(m.span())
print(m.group())
result:
(14, 17)
dog
re.findall()
在不调整pattern的情况下,search只能找到字符串中最靠前的目标,为了找到所有目标,可以使用findall()函数
import re
pattern = 'dog'
m = re.findall(pattern, "I'm not black dog but white dog")
print(m)
result:
['dog', 'dog']
findall也可以指定字符串起始位置和终止位置,但需要改写一下方式
import re
p = 'dog'
pattern = re.compile(p)
m = pattern.findall("I'm not black dog but white dog", 13, 20)
print(m)
result:
['dog']
re.sub()
sub()可以用来替换找到的目标,参数为(pattern, repl, string, count)
repl可以为替换目标,也可以为函数,需要入参,参数为match,也需要return回东西;
count是替换次数,默认数量0,即全部替换
import re
def cat(match):
print(match)
return 'cat'
m = re.sub("dog", cat, "I'm not black dog but white dog")
print(m)
result:
<re.Match object; span=(14, 17), match='dog'>
<re.Match object; span=(28, 31), match='dog'>
I'm not black cat but white cat
pattern书写规则
定位的符号
如果我不喜欢黑毛,只喜欢白毛,只想定位white dog,就可以使用括号突出我需要定位的目标,并在周围填写目标周围的信息即可实现定位
import re
pattern = "white (dog)"
m = re.search(pattern, "I'm not black dog but white dog")
print(m)
print(m.group(0))
print(m.group(1))
result:
<re.Match object; span=(22, 31), match='white dog'>
white dog
dog
但我又改变主意了,我突然又喜欢黑毛了,我两个都想定位,此时需要使用两个括号即可
import re
pattern = "black (dog) but white (dog)"
m = re.search(pattern, "I'm not black dog but white dog")
print(m)
print(m.group(0))
print(m.group(1))
print(m.group(2))
result:
<re.Match object; span=(8, 31), match='black dog but white dog'>
black dog but white dog
dog
dog
可以看到group的参数是递增的,第几个括号填几就可以了
定位模糊信息
假如我就是喜欢白毛,是不是狗都无所谓,便可以将括号中的内容正则化,.指代单个非回车的字符,*代表任意多,两者组合起来便可代表任意长度的字符串,其他表示方法后面介绍
import re
pattern = "white (.*)!"
m = re.search(pattern, "I'm not black dog but white dog!")
print(m)
print(m.group(0))
print(m.group(1))
result:
<re.Match object; span=(22, 32), match='white dog!'>
white dog!
dog
限制
最短匹配和贪婪匹配
看这样一个例子:
import re
pattern = "white (.*)!"
m = re.search(pattern, "I'm not black dog but white dog!I don't like black dogs!")
print(m)
print(m.group(0))
print(m.group(1))
result:
<re.Match object; span=(22, 55), match="white dog!I don't like black dogs!">
white dog!I don't like black dogs!
dog!I don't like black dogs
可以看到white和!直接有两组,一组短一组长,如果不作指定,一定会返回最长的那组,这种匹配方式叫做贪婪匹配。
如果想要匹配最短的一组,需要加上问号,注意不要加错地方
import re
pattern = "white (.*?)!"
m = re.search(pattern, "I'm not black dog but white dog!I don't like black dogs!")
print(m)
print(m.group(0))
print(m.group(1))
result:
<re.Match object; span=(22, 32), match='white dog!'>
white dog!
dog
长度限制
使用{},具体后面讲
正确书写你的匹配模式
前面讲过,匹配任意字符串需要用到.*的模式,只要掌握如何确定字符集和数量,基本就可以熟练使用正则了
确定你的字符集
字符 | 作用 |
---|---|
. | 匹配任意字符,除了换行符,当re.DOTALL标记被指定时,则可以匹配包括换行符的任意字符 |
^ | 匹配字符串的开头 |
$ | 匹配字符串的末尾。 |
举个简单的例子
import re
pattern = "^(.*)$"
m = re.search(pattern, "I'm not black dog but white dog!")
print(m)
print(m.group())
result:
<re.Match object; span=(0, 32), match="I'm not black dog but white dog!">
I'm not black dog but white dog!
这就从头到尾全部拿下来了
如果要指定字符集,则需要使用中括号[],示例中只匹配由只包含d,o,g三种及以下种类字符的字符串,需要注意的是,中括号中的字符种类虽然多,但他在数量上只代表一个字符
import re
pattern = ".* ([god]*) .*"
m = re.findall(pattern, "I'm not black dog but white dogs!")
print(m)
result:
['dog']
如果不想匹配到包含某些字符的字符串,使用^就可以了
import re
pattern = " ([^t]*) "
m = re.findall(pattern, "I'm not black dog but white dogs!")
print(m)
result:
['black dog']
可以写在中括号里的符号如下:
符号 | 含义 |
---|---|
\d | 匹配一个数字字符。等价于 [0-9] |
\D | 匹配一个非数字字符。等价于 [^0-9] |
\s | 匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v] |
\S | 匹配任何非空白字符。等价于 [^ \f\n\r\t\v] |
,n\w | 匹配包括下划线的任何单词字符。等价于’[A-Za-z0-9_]’ |
\W | 匹配任何非单词字符。等价于 ‘[^A-Za-z0-9_]’ |
确定字符数量
数量字符控制前一个字符的匹配次数,这也是我刚才在强调[中括号]只代表一个字符的原因所在,含义表格如下:
字符 | 含义 |
---|---|
* | 匹配0次或1次或多次 |
+ | 匹配1次或多次 |
? | 匹配0次或1次 |
{m} | 匹配m次,既不能多也不能少 |
{m,n} | 匹配[m,n]次,m,n可以有一边为空,但逗号得留下,即{m,}或{,n} |
import re
pattern = "black ([dogs]{3}) .*"
m1 = re.findall(pattern, "I'm not black do but white dog!")
m2 = re.findall(pattern, "I'm not black dog but white dog!")
m3 = re.findall(pattern, "I'm not black dogs but white dog!")
print(m1)
print(m2)
print(m3)
result:
[]
['dog']
[]
可以看到,只有字符串长度正好是3时才可以匹配上,少于或多余都不可以。
如果写作{2,4}即可全部匹配
import re
pattern = "black ([dogs]{2,4}) .*"
m1 = re.findall(pattern, "I'm not black do but white dog!")
m2 = re.findall(pattern, "I'm not black dog but white dog!")
m3 = re.findall(pattern, "I'm not black dogs but white dog!")
print(m1)
print(m2)
print(m3)
result:
['do']
['dog']
['dogs']
暂时就写到这里吧,肝了三个小时,明天还得上班,哭哭
剩下诸如逻辑符或者命名之类乱七八糟的有时间以后再写吧,不过八成不会有以后了,上边写的这些差不多已经够用了
转载,注明,出处!阿里嘎多