子组不捕获匹配的内容--结果与实际不符呢
import urllib.requestimport re
def open_url(url):
req = urllib.request.Request(url) # urllib.request.Request讲解见14.2.1、14.3.1,举例见p14_4.py、p14_5.py
req.add_header('User-Agent', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36') # add_header讲解见14.3.1,举例见爬取猪八戒词条
response = urllib.request.urlopen(req)
#response
#print(response)
html = response.read().decode('utf-8')
return html
def get_img(html):
p = r'(?:(?:?\d?\d|2\d|25)\.){3}(?:?\d?\d|2\d|25)' # ip由四段数字组成:XXX.XXX.XXX.XXX
iplist = re.findall(p, html)
for each in iplist:
print(each)
if __name__ == '__main__': # 见13.4(P147-149)
url = 'https://proxy.seofangfa.com'
get_img(open_url(url)) # 看不懂???!!!
运行后获得:
36.134.91.82
117.157.197.18
103.59.151.99
111.23.16.25
203.34.48.10
45.189.254.70
43.255.113.23
43.255.113.23
43.255.113.23
43.255.113.23
与实际网页对比如下:
红框处不同,是不是正则表达式有错造成的呢?完全按小甲鱼教学视频上敲的哦
本帖最后由 isdkz 于 2022-5-5 11:16 编辑
这个正则表达式确实有点问题,
因为第一种情况 ?\d?\d 可以匹配两位且第一位不是 0,1开头的,
250 就不是 以 0、1 开头的,所以只匹配了两位就不匹配了,你可以把正则的位置换一下
对你的代码修改如下:
import urllib.request
import re
def open_url(url):
req = urllib.request.Request(url) # urllib.request.Request讲解见14.2.1、14.3.1,举例见p14_4.py、p14_5.py
req.add_header('User-Agent', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36') # add_header讲解见14.3.1,举例见爬取猪八戒词条
response = urllib.request.urlopen(req)
#response
#print(response)
html = response.read().decode('utf-8')
return html
def get_img(html):
p = r'(?:(?:?\d?\d|2\d|25)\.){3}(?:2\d|25|?\d?\d)' # 改了这里最后一段的位置,把 ?\d?\d 放到最后
iplist = re.findall(p, html)
for each in iplist:
print(each)
if __name__ == '__main__': # 见13.4(P147-149)
url = 'https://proxy.seofangfa.com'
get_img(open_url(url)) # 看不懂???!!!
isdkz 发表于 2022-5-5 06:19
这个正则表达式确实有点问题,
因为第一种情况 ?\d?\d 可以匹配两位且第一位不是 0,1开头的,
感谢,按大神指点的修改后确实可以了。
不过我想继续问下:
大神你说:因为第一种情况 ?\d?\d 可以匹配两位且第一位不是 0,1开头的,
而我记得小甲鱼在教材里14.5.4说:\d\d表示可以匹配0或1开头的
所以我想问的是:
1、 ?\d?\d 是不是应该等同于?\d?\d
2、如果等同的话,大神的说法不是和小甲鱼的说法不一致了吗? lzb1001 发表于 2022-5-5 10:54
感谢,按大神指点的修改后确实可以了。
不过我想继续问下:
?\d?\d 不等同于 ?\d?\d 也不等同于 \d\d,
比 多出一个 逗号字符,
在中括号里表示范围应该用 -,即 ?\d?\d
等同于 ?\d?\d,
那个 ?表示匹配 0 次或 1 次,
也就是说 0 或 1 不一定要匹配上,这时候就少了 1 位,
也就是说 ?\d?\d 除了可以匹配以0或1开头的三位数以外,
还可以匹配不以0或1开头的两位数,
这样的话就没有后边的 2\d 或 25什么事了,
他匹配够两位就不继续往下匹配了,
所以我换了一下顺序,先看 2\d 或 25 能不能匹配上,
再来看 ?\d?\d 本帖最后由 lzb1001 于 2022-5-5 12:00 编辑
isdkz 发表于 2022-5-5 11:15
?\d?\d 不等同于 ?\d?\d 也不等同于 \d\d,
比 多出一个 逗号字符,
有点绕,三个的区别看晕了,整理下:
等同于 表示含义
\d\d ? 可以匹配两位且第一位不是 0,1开头的?
\d\d \d\d ?
\d\d \d\d ?
lzb1001 发表于 2022-5-5 11:56
有点绕,三个的区别看晕了,整理下:
等同于 表示含义
\d\d 等同于 \d\d,
而 \d\d 中的 “,” 就是一个普通的逗号字符,所以除了 0 或 1 还可以匹配逗号,
是 ?\d?\d 可以匹配两位数字且第一位不是 0,1开头的,
关于正则表达式中 “?” 的用法你可以去查一下,
正则表达式是需要系统地去学习的,刚开始接触可能确实不太好理解 本帖最后由 lzb1001 于 2022-5-5 12:09 编辑
三种表达式运行的结果为什么都一样?更晕了:
第一种:p = r'(?:(?:2\d|25|?\d?\d)\.){3}(?:2\d|25|?\d?\d)'
103.133.177.141
47.115.6.196
183.247.194.203
175.178.89.245
39.174.28.139
45.167.89.93
112.78.14.152
112.78.14.4
181.129.2.90
112.78.14.23
第二种:p = r'(?:(?:2\d|25|?\d?\d)\.){3}(?:2\d|25|?\d?\d)'
103.133.177.141
47.115.6.196
183.247.194.203
175.178.89.245
39.174.28.139
45.167.89.93
112.78.14.152
112.78.14.4
181.129.2.90
112.78.14.23
第三种:p = r'(?:(?:2\d|25|?\d?\d)\.){3}(?:2\d|25|?\d?\d)'
103.133.177.141
47.115.6.196
183.247.194.203
175.178.89.245
39.174.28.139
45.167.89.93
112.78.14.152
112.78.14.4
181.129.2.90
112.78.14.23
第二种和第三种的写法其实是一样的,对吗? lzb1001 发表于 2022-5-5 12:08
三种表达式运行的结果为什么都一样?更晕了:
嗯嗯,第二种和第三种是一样的,
而 第一种可以匹配逗号字符,也就是说你这里没有逗号自然没有区别了,
你把最后一段的第一个数字换成逗号你就可以看出区别了
isdkz 发表于 2022-5-5 17:43
嗯嗯,第二种和第三种是一样的,
而 第一种可以匹配逗号字符,也就是说你这里没有逗号自然没有区别了 ...
最后一段的第一个数字换成逗号?
没看懂是指哪一段的第一个数字,请明示,谢谢大神 lzb1001 发表于 2022-5-5 20:11
最后一段的第一个数字换成逗号?
没看懂是指哪一段的第一个数字,请明示,谢谢大神
>>> import re
>>> p = r'(?:(?:2\d|25|?\d?\d)\.){3}(?:2\d|25|?\d?\d)'
>>> re.match(p, "103.133.177.,41")
<re.Match object; span=(0, 15), match='103.133.177.,41'>
>>> p = r'(?:(?:2\d|25|?\d?\d)\.){3}(?:2\d|25|?\d?\d)'
>>> re.match(p, "103.133.177.,41")
>>>
页:
[1]