正则(regeylar expression)
import re
爬虫:网页源码里面的url都提取出来
提取我们想要的数据
分析日志:拿到所有的ip,
正则表达式的原理:
\d+ “ab123 4”
首先找a是否是数字,然后b不是,继续1是,进行储存,2、3是继续储存,之后空格不是,之前暂存的退一步,然后只要前3个符合规则的作为结果:123
简单说:只要找到符合条件的字符,之后的字符不符合条件,就会返回前面匹配到的字符
小坑:
#1
>>> re.search("\d*","无ada46465").group()
''
(*)满足第一个无,后面a不满足返回第一个条件
#2
re.findll会逐一匹配"1ab2c3d4",不匹配返回””
>>> re.findall("\d?","1ab2c3d4")
['1', '', '', '2', '', '3', '', '4', '']
#3
“a.b” 只能匹配a和b之间的一个字符,所有会报错
>>> re.search("a.b","a13bc123 1").group()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'group
\d表示数字,\D表示非数字
>>> import re
#1 \d 表示数字
>>> re.search(r"\d","ab123f").group()
'1'
#2 \D 表示非数字
>>> re.search(r"\D","ab123f").group()
'a'
>>> re.search(r"\D","1ab123f").group()
'a'
\w表示[a-zA-Z_0-9中文],\W非[a-zA-Z_0-9中文]
#1 \w 表示[a-zA-Z_0-9中文]
>>> re.search(r"\w","1ab123f").group()
'1'
>>> re.search(r"\w","_").group()
'_'
>>> re.search(r"\w","A").group()
'A'
>>> re.search(r"\w","b").group()
'b'
>>> re.findall(r"\w","国家")
['国', '家']
#2 \W 非[a-zA-Z_0-9中文]
>>> re.search(r"\W","!").group()
'!'
>>> re.search(r"\W"," ").group()
' '
>>> re.search(r"\W",",").group()
','
\s表示空白(\n,\t,\r ),\S非空白(\n,\t,\r )
#1 \s 表示空白(\n,\t,\r )
>>> re.search(r"\s","\n").group()
'\n'
>>> re.search(r"\s","\t").group()
'\t'
>>> re.search(r"\s","\r").group()
'\r'
>>> re.search(r"\s"," ").group()
' '
#2 \S 非空白(\n,\t,\r )
>>> re.search(r"\S"," !").group()
'!'
\b\B
量词:
#1 + 匹配一个或多个
尽量多的匹配
正则表达式的贪婪性
>>> re.search("\d+","abc123 1").group()
'123'
>>> re.search("\d+","abc123 1").group()
'123'
>>> re.search("\s+","abc123 1").group()
' '
>>> re.search("\w+","abc123 1").group()
'abc123'
>>> re.search("\S+","abc123 1").group()
'abc123'
>>> re.search("\W+","abc123 1").group()
' '
>>> re.search("\D+","abc123 1").group()
'abc'
#2 +? *? 最小匹配,抑制贪婪性
>>> re.search("\w+","abc123 1").group()
'abc123'
>>> re.search("\w+?","abc123 1").group()
'a'
>>> re.search("\w*?","abc123 1").group()
''
#3 * 匹配0次,或多次
>>> re.search("\w*","abc123 1").group()
'abc123'
>>> re.search("\w*"," ").group()
''
#4 {m,n} 匹配指定次数,例如匹配3次 {3}
>>> re.search("\d{3}","abd12 456 45").group()
'456'
>>> re.search("\w{3}","abd12 456 45").group()
'abd'
>>> re.search("\w{1,3}","abd12 456 45").group()
'abd'
知识点1:至少1个{1,} 等价与w+
>>> re.search("\w{1,}","abd12 456 45").group()
'abd12'
知识点2: | 表示或的关系
>>> re.search("\w{2}|\d{4}","abd12 456 45").group()
'ab'
#3 ? 匹配0次,或1次
>>> re.search("\d?","abd12 456 45").group()
''
>>> re.search("\d?","1bd12 456 45").group()
'1'
知识点1:re.findll会逐一匹配"1ab2c3d4",不匹配返回””
>>> re.findall("\d?","1ab2c3d4")
['1', '', '', '2', '', '3', '', '4', '']
#4 . 匹配任意字符,除了换行符(\r \t \n),当re.DOTALL标
“a.b“只能包含a和b之间的一个字符
>>> re.search(r"a.b","a1b").group()
'a1b'
>>> re.search(r"a.b","a b").group()
'a b'
>>> re.search(r"a.b","aAb").group()
'aAb'
>>> re.search(r"a.b","a\Tb").group()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'group'
知识点1:"a.*b"表示a和b之间最大匹配
>>> re.search(r"a.*b","a1 db 123b").group()
'a1 db 123b'
知识点2:"a.*?b"表示a和b之间最小匹配
>>> re.search(r"a.*?b","a1 db 123b").group()
'a1 db'
re.match
#从开始位置开始匹配,如果开头没有则无
示例:
Ø 1 match从开头匹配
>>> import re
>>> re.match(r"abc","abcde")
<re.Match object; span=(0, 3), match='abc'>
解析:
re.Match object:匹配对象
span=(0, 3):范围0~3
match='abc':匹配内容“abc“
Ø 2 \d:表示匹配一个数字
>>> re.match("\d","1abcde")
<re.Match object; span=(0, 1), match='1'>
>>> re.match("\d","2abcde")
<re.Match object; span=(0, 1), match='2'>
>>> re.match("\d","3abcde")
<re.Match object; span=(0, 1), match='3'>
>>> re.match("\\d","3abcde")
<re.Match object; span=(0, 1), match='3'>
>>> re.match(r"\d","3abcde") #文件里面,防止转义前面加一个r
<re.Match object; span=(0, 1), match='3'>
\d 的意思就是 digit
Ø 3 匹配到,返回一个匹配对象,否则返回None
如果开头没匹配:
>>> re.match(r"\d","a3abcde")
>>> result = re.match(r"\d","a3abcde")
>>> type(result)
<class 'NoneType'>
返回一个None
如果匹配到:
>>> result = re.match(r"\d","3abcde")
>>> type(result)
<class 're.Match'>
就是匹配结果的对象
4 匹配到的对象使用result.group()打印结果
>>> result = re.match(r"\d","123")
>>> result
>>> result.group()
'1'
如果返回值是None,就会报错
>>> re.match(r"\d","abcd")
>>> result = re.match(r"\d","abcd")
>>> result.group()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'group'
re.search
>>> print(re.search(r"\d","abc1de"))
<re.Match object; span=(3, 4), match='1'>
解析:
re.Match object:匹配对象
span=(3, 4):范围3~4
match='1‘:匹配内容“1“
Ø 1 re.search从任意位置匹配
从字符串中间第一个数字找,找到之后就返回
>>> print(re.search(r"\d","ab2c1d3e"))
<re.Match object; span=(2, 3), match='2'>
正则的规则是,找到第一个,
就不会往后面找了,所以只找到了2
Ø 2 匹配到,返回一个匹配对象,否则返回None
>>> re.search(r"\d","abcde")
>>> print(re.search(r"\d","abcde"))
None
>>> type(re.search(r"\d","abcde"))
<class 'NoneType'>
3 匹配到的对象使用result.group()打印结果
>>> re.search(r"\d","ac1db")
<re.Match object; span=(2, 3), match='1'>
>>> result = re.search(r"\d","ac1db")
>>> result.group()
'1'
如果返回值是None,就会报错
>>> result = re.search(r"\d","acdb")
>>> result.group()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'group'
re.compile
#可以把我们想要的正则表达式编译成一个对象,可以进行复用
1 编译正则,复用
好处:编译了一个结果,可以使用不同的匹配( import re类 )方法
存在变量里,方便复用:
pattern = re.compile(r"\d")
1、re.match
>>> pattern = re.compile(r"\d")
>>> type(pettern)
>>> type(pattern)
<class 're.Pattern'>
>>> pattern.match("1ab")
<re.Match object; span=(0, 1), match='1'>
>>> pattern.match("1ab").group()
'1'
2、re.search
>>> pattern2 = re.compile(r"\d")
>>> type(pattern2)
<class 're.Pattern'>
>>> pattern2.search("ab1sb")
<re.Match object; span=(2, 3), match='1'>
>>> pattern2.search("ab1sb").group()
'1'
re.findall
Ø 1 搜索这个字符串,匹配所有该字符串,返回一个list
>>> re.findall(r"\d","a1b2c3")
['1', '2', '3']
>>> result = re.findall(r"\d","a1b2c3")
>>> result
['1', '2', '3']
Ø 2 匹配到,返回一个list,否则返回空列表[]
>>> re.findall(r"\d","abc")
[]
re.I
#使匹配对大小写不敏感
re.M #多行匹配,影响^和$
re.S #使匹配包括换行在内的所有字符串
^ #匹配字符串的开头
$ #匹配字符串的末尾
[…] #用来表示一组字符,单独列出:[amk]匹配
[^…] #不在[]中的字符:[^abc]匹配除了a,b,c之外
re* #匹配0个或多个的表达式
re+ #匹配1个或多个的表大师
re? #匹配0个或1个由前面的正则表达式定义的片段
re{ n}
练习1:输入一些内容匹配OK是否存在!
知识点:根据返回是否为None进行判断
#1 re.serch
import re
s = input("请输入一些内容:")
if re.search(r"ok",s):
print(True)
else:
print(False)
#1 输出结果:
D:\>py b.py
请输入一些内容:is ok bey!
True
#2 输出结果
D:\>py b.py
请输入一些内容:aaaa
False
#2 re.match
import re
s = input("请输入一些内容:")
if re.match(r"ok",s):
print(True)
else:
print(False)
#1 输出结果:
D:\>py b.py
请输入一些内容:ok is my
True
#2 输出结果
D:\>py b.py
请输入一些内容:aaaa
False
#3 re.findall
import re
s = input("请输入一些内容:")
if re.findall(r"ok",s):
print(True)
else:
print(False)
#1 输出结果:
D:\>py b.py
请输入一些内容:is ok bye
True
#2 输出结果:
D:\>py b.py
请输入一些内容:aaa
False
#4 re.compile
import re
s = input("请输入一些内容:")
result = re.compile(r"ok")
if re.search(result,s):
print(True)
else:
print(False)
#1 输出结果:
D:\>py b.py
请输入一些内容:is ok bey
True
#2 输出结果:
D:\>py b.py
请输入一些内容:aaaa
False