qasa 发表于 2026-3-3 21:16:32

鱼总零基础第一版, 正则表达式, 模块级别和模式对象级别用法问题

一 ,
                模块级别 和 模式对象级别 对比
        以search为例子
模块:re.search(r’正则表达式’,’要匹配的字符串’)
模式对象:search(r’要匹配的字符串’,开始位置,结束位置)
        模块级别 和 模式对象级别 在我这里认知比较模糊感觉好蒙的

        现在知道的就是模块级别多了个正则表达式   就是一行模式
                模式级别就是多行模式正则表达式在外面写过了 所以这里不用写了

二,
                照片上的问题是这样的
        url = 'http://tieba.baidu.com/p/23423625'
name= for each in url]
name
['h', 't', 't', 'p', ':', '', '', 't', 'i', 'e', 'b', 'a', '.', 'b', 'a', 'i', 'd', 'u', '.', 'c', 'o', 'm', '', 'p', '', '2', '3', '4', '2', '3', '6', '2', '5']

这是我对图片的理解 鱼总说这个代码片段可以直接获得最后一段文件名为何我得到的是一坨乱码,搞不定,搞不懂

三 ,
        我理解的
                if __name__ == '__main__':
                        url = 'http://tieba.baidu.com/p/23423625'
                        get_img(open_url(url)
                        第三个问题在这里 这里是   从里面到外面依次执行吗先执行 open_url(url) 暂时成为BB   在执行 get_img(BB)吗?

FishC 发表于 2026-3-3 21:17:45

鱼油你好!针对你的三个问题,我来逐一解答,希望能帮你理清思路。

一、正则表达式的模块级别与模式对象级别

你的理解有些混淆,让我来澄清一下:


[*]模块级别:直接使用 re 模块提供的函数,例如 re.search(pattern, string)。每次调用时,它都会在内部编译正则表达式,适合一次性使用。
[*]模式对象级别:先用 re.compile(pattern) 将正则表达式编译成一个“模式对象”(Pattern object),然后使用这个对象的方法,例如 pattern.search(string)。这样编译一次后可以重复使用,效率更高,适合多次使用同一正则表达式的情况。


你提到的“一行模式”和“多行模式”其实是正则表达式的匹配模式(比如用 re.M 标志),这与模块级别或对象级别无关,两种方式都可以设置这些模式。

简单对比:


# 模块级别用法(每次调用都编译)
import re
result = re.search(r'正则表达式', '要匹配的字符串')

# 模式对象级别用法(编译一次,重复使用)
pattern = re.compile(r'正则表达式')
result = pattern.search('要匹配的字符串')


所以,选择哪种方式取决于你是否需要重复使用同一个正则表达式。如果只用一次,模块级别方便;如果用多次,模式对象级别更高效。

二、关于获取URL最后一段文件名的问题

你提供的代码片段:


url = 'http://tieba.baidu.com/p/23423625'
name =
name


这个代码不会得到文件名,反而会产生“乱码”。原因是:


[*]for each in url 会遍历字符串 url 中的每个字符(例如 'h', 't', 't', 'p' 等),而不是按 "/" 分割后的部分。
[*]对每个字符调用 split("/"),由于字符中不包含 "/",结果会返回包含原字符的列表(例如 ['h'], ['t'], ['t'], ['p'] 等),最终得到一个嵌套列表,看起来像乱码。


正确获取文件名的方法应该是:


url = 'http://tieba.baidu.com/p/23423625'
# 使用 split("/") 分割整个字符串,然后取最后一部分
filename = url.split("/")[-1]
print(filename)# 输出:23423625


这样就能直接得到最后的文件名 "23423625"。如果你想要更健壮的方式(比如处理可能的查询参数),可以使用其他方法,但基础分割就够用了。

三、关于函数调用的执行顺序

你的理解完全正确!在代码:


if __name__ == '__main__':
    url = 'http://tieba.baidu.com/p/23423625'
    get_img(open_url(url))


执行顺序是从内到外:


[*]先执行 open_url(url),得到返回值(假设你称之为 BB)。
[*]然后将这个返回值 BB 作为参数,传递给 get_img(BB) 函数执行。


所以,确实是先执行 open_url(url),再执行 get_img(...)。这种顺序是标准的函数调用求值方式,确保参数先计算完毕再调用函数。

希望这些解释能帮你解决问题!继续加油学习,有任何疑问随时来问。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

不二如是 发表于 2026-3-3 22:00:51

{:13_397:} 先说答案吧:


[*]compile决定模块级别区别
[*]字符串for循环是按字符
[*]函数调用先算括号里面

这三个问题就彻底通了。

一、模块级别 vs 模式对象级别
模块级别

re.search(r'正则', '字符串')
每次都会临时编译正则,用完就丢,适合一次性匹配。

模式对象级别:

pattern = re.compile(r'正则')
pattern.search('字符串', start, end)
只编译一次,可重复使用,性能更好~

本质区别:


[*]是否提前compile
[*]和“单行/多行”没关系。


二、为什么你得到一坨字符?

你写的是:

name = for each in url]
问题是:

for each in url
字符串是可迭代的 → 会一个字符一个字符取。

所以 each 是:

'h' 't' 't' 'p' ...
当然结果乱七八糟。

正确写法:

url.split("/")[-1]

三、嵌套函数执行顺序

get_img(open_url(url))

执行顺序:

先执行 open_url(url),得到返回值,再执行 get_img(返回值)。

规则:


[*]先算参数,再调用函数。

player-none 发表于 2026-3-4 17:41:09

不二如是 发表于 2026-3-3 22:00
先说答案吧:




你那个表情笑死我了hhhhhhhhh

player-none 发表于 2026-3-4 17:44:49

一. 没看懂你提问的是啥{:10_282:}

二. each 其实是url里的每一个字符
如果你想搞到 23423625 的话要用 url.split('/')[-1]
split其实就是根据分隔符把字符串分成好几部分,例如 'ab/cd'.split('/') -> ['ab', 'cd']

三. 是的

不二如是 发表于 2026-3-4 17:45:41

player-none 发表于 2026-3-4 17:41
你那个表情笑死我了hhhhhhhhh

鱼C官方表情包{:13_394:}

qasa 发表于 2026-3-4 21:15:39

player-none 发表于 2026-3-4 17:44
一. 没看懂你提问的是啥

二. each 其实是url里的每一个字符


问题是同 不二如是朋友说的一样 我不懂 模块 和 模式的区别 区分不开
现在懂了看见他的解答了
谢谢你回我

qasa 发表于 2026-3-4 21:16:12

不二如是 发表于 2026-3-3 22:00
先说答案吧:




谢谢朋友解答,发现每次都是您,真的很感谢

不二如是 发表于 2026-3-5 09:26:15

qasa 发表于 2026-3-4 21:16
谢谢朋友解答,发现每次都是您,真的很感谢

哈哈,鱼C是我家
页: [1]
查看完整版本: 鱼总零基础第一版, 正则表达式, 模块级别和模式对象级别用法问题