# 内存垃圾回收机制:
# 工作原理:引用计数
# 引用就+1 释放就是-1 当计数为0时 就会被垃圾回收机制回收 # 标记清除:解决循环引用导致的内存泄漏
# 标记:GC roots可以直接或间接访问到的数据,都标记为存活状态
# 清除:触发标记清楚动作后,将所有存活状态的变量复制到新空间,将老空间中的所有值清空
# 分代回收:提高回收效率的优化策略
# 分代:将产期存活的变量移至更高代,检查频率降低
# 回收:回收的依据还是采用引用计数
# 循环引用 => 内存泄漏
# ls1 = [666]
# ls2 = [888]
# ls1.append(ls2)
# ls2.append(ls1)
# print(ls1) [666, [888, [...]]] # print(ls2)[888, [666, [...]]] # re 正则
# 一什么是正则?
# 正则就是用一些具有特殊含义的符号组合到一起(称之为正则表达式)来描述字符或者字符串的方法
# 或者说:正则就是用来描述一类事物的规则,(在python中)它内嵌在python中,并通过re模块实现。正则表达式模式被编译成一系列的字节码。然后由c编写的皮匹配引擎执行
# 二常用匹配模式(元字符)
# \w 匹配字母数字及下划线
# \W 匹配非字母数字下划线
# \s 匹配任意空白字符 等价于[\t\n\r\f]
# \S 匹配任意非空字符
# \d 匹配任意数字,等价于[0-9]
# \D 匹配任意非数字
# \A 匹配字符串开始
# \Z 匹配字符串结束,如果是存在换行,只匹配到换行前的结束字符串
# \z 匹配字符串结束
# \G 匹配最后匹配完成的位置
# \n 匹配一个换行符
# \t 匹配一个制表符
# ^ 匹配字符串的开头
# $ 匹配字符串的末尾
# . 匹配任意字符,除来换行符,当re.DOTALL标记被指定是,则可以匹配包含换行符的任意字符
# [...] 用来表示一组字符,单独列出来:[amk] 匹配 'a','m'或'k'
# [^....] 不在[]的字符: [^abc]: 匹配除了a b c 之外的字符
# * 匹配0个或多个表达式
# + 匹配1个或多个的表达式
# ? 匹配0个或1个有前面的正则表达式定义的片段,非贪婪方式
# {n} 精确匹配n个前面表达式
# {n,m} 匹配n到m次由前面的正则表达式定义的片段,贪婪方式
# a|b 匹配a或b
# () 匹配括号内的表达式,也表示一个组
import re
# s="12345http://www.baidu.com/12htp46"
# res=re.findall(r'http://www.baidu.com/',s)
# print(res) #['http://www.baidu.com/']
# 转义
# print(re.findall(r'\\a',r'123\adc')) #['\\a'] 用来转义,在正则中\\a代表\a 原义的字符串前面要加r
# print(re.findall('a',r'123\abcabc')) #['a', 'a'] 字母
# print(re.findall('\d',r'123\abcabc')) #['1', '2', '3'] 数字
# print(re.findall('\D',r'123\abcabc')) #['\\', 'a', 'b', 'c', 'a', 'b', 'c']非数字
# print(re.findall('[0-9]',r'123\abcabc')) #['1', '2', '3'] 匹配任意一个数字 # 列表中-在中间表示从0到9之间的数字 [- 0 9 ]或者[0 9 -] 表示匹配列表中 - 0 9 三个中的任意一个 # print(re.findall('[A-z]|[a-z]',r'123\abcabcABC'))
# #['\\', 'a', 'b', 'c', 'a', 'b', 'c', 'A', 'B', 'C'] ascii码表中[65-122]|[97-122]包含\
# print(re.findall('[A-Z]|[a-z]',r'123\abcabcABC'))
# #['a', 'b', 'c', 'a', 'b', 'c', 'A', 'B', 'C']
# print(re.findall('[0-3]|[6-9]',r'123\abcabcABC48'))
# #['1', '2', '3', '8']
# print(re.findall('[A-Za-z0-9好]',r'123[\abcabcABC好好'))
# #['1', '2', '3', 'a', 'b', 'c', 'a', 'b', 'c', 'A', 'B', 'C', '好', '好']
# print(re.findall('\w',r'123[\abcabcABC*_12'))
# #['1', '2', '3', 'a', 'b', 'c', 'a', 'b', 'c', 'A', 'B', 'C', '_', '1', '2'] 字母数字下划线
# print(re.findall('\S',r'123[\abcabcABC好好*_12')) #任意非空字符
# ['1', '2', '3', '[', '\\', 'a', 'b', 'c', 'a', 'b', 'c', 'A', 'B', 'C', '好', '好', '*', '_', '1', '2']
# print(re.findall('\s','123[\n\t\r\abcabcABC好好*_12')) #匹配所有任意空白字符
# ['\n', '\t', '\r']
# print(re.findall('.','123[\a b\nc\ta\rbcABC好好*_12')) #匹配任意字符 除了换行符
# ['1', '2', '3', '[', '\x07', ' ', 'b', 'c', '\t', 'a', '\r', 'b', 'c', 'A', 'B', 'C', '好', '好', '*', '_', '1', '2']
# print(re.findall('.','\a')) #['\x07'] # print(re.findall('ab',r'123\abcabc')) #['ab', 'ab']
# print(re.findall('[a-z]{2}',r'123\abcabc')) #['ab', 'ca', 'bc'] {n} n代表个数 a-z中的任意两个
# print(re.findall('o{2,}','foodfooood')) #['oo', 'oooo'] {n,}n到多个 贪婪匹配 尽可能的多的匹配
# print(re.findall('o{1,2}','foodfooood')) #['oo', 'oo', 'oo'] {n,m} n到m个贪婪匹配,尽可能多的匹配(1到2个)
# print(re.findall('zo*','zzozoozooo')) # ['oo', 'oo', 'oo'] {,n} 0到n个 贪婪匹配
# print(re.findall('zo+','zzozoozooo')) #['zo', 'zoo', 'zooo'] {,n} 1到n个 贪婪匹配
# print(re.findall('zo?','zzozoozooo')) #['z', 'zo', 'zo', 'zo'] {0,1} 0到1个,贪婪匹配,尽可能多的匹配
# print(re.findall('zo+?','zzozoozooo')) #['zo', 'zo', 'zo'] {1,n} 1到n个,非贪婪匹配,尽可能少的匹配 == {1}
# print(re.findall('zo*?','zzozoozooo')) #['z', 'z', 'z', 'z'] {0,n} 1到n个,非贪婪匹配,尽可能少的匹配 == {0} # 多行匹配
# re.S 将\n也能被.匹配 re.I :不区分大小写 re.M 结合^ $ 来使用,完成多行匹配
# print(re.findall('^owen.+vv$','owen_name_vv\nowen_age_vv\nzero_owen\nowen_oo',re.M))
# ['owen_name_vv', 'owen_age_vv'] # result=re.findall(r'^http://.+/$','http://www.baidu.com/\nhttp://www.sina.com.cn/',re.M)
# print(result)
# ['http://www.baidu.com/', 'http://www.sina.com.cn/']
# for res in result:
# print(res)
# http: // www.baidu.com /
# http: // www.sina.com.cn /
# t=re.match('http://(.+)/',res,) #相当于search的从头开始找
# print(t)
# t=re.match('http://(.+)/',res,).group()
# print(t)
# http: // www.baidu.com /
# http: // www.sina.com.cn /
# <re.Match object; span=(0, 21), match='http://www.baidu.com/'>
# <re.Match object; span=(0, 23), match='http://www.sina.com.cn/'>
# print(t.group(0)) # group(0)代表的是('http://(.+)/) 0:最外层的括号
# <re.Match object; span=(0, 21), match='http://www.baidu.com/'>
# <re.Match object; span=(0, 23), match='http://www.sina.com.cn/'>
# print(t.group(1)) # group(1)代表的是('http://(.+)/) 1:最外层的里面的左边的第一个左括号(
# www.baidu.com
# www.sina.com.cn # 分组:
# 1从左往右数 " ( " 进行编号,自己的分组从1开始,group(0)代表匹配的目标整体
# 2.(?:....):取消所属分组,()就是普通的括号,可以将里面的信息作为整体包裹,但不产生分组
# regexp = re.compile ('(?:(?:http://)\((.+)\)/)') #\( \) 转义成括号
# target=regexp.match('http://(www.baidu,com)/')
# print(target.group(0)) #http://(www.baidu,com)/ #将里面的信息作为整体包裹,但不产生分组
# print(target.group(1)) #www.baidu,com # 替换:
# 1.不参与匹配的原样带下 2 参与匹配的都会被替换为指定字符串
# 3 在不指定字符串值 \num拿到具体分组 4 其他字符串信息都是原样字符串
# print(re.sub('《(?:[a-z]+)(\d+)(.{2})',r'\0\2abc\2\1','《abc123你好》'))
# 0:《abc 1:(123) 2:(你好) 》取不到不参与替换原样带下
# 你好abc你好123》 # print(re.sub('《(?:[a-z]+)(\d+)(.{2})',r'\1\2','《abc123你好》')) # print(re.findall('[a-z]{2}',r'123\abcabce')) #['ab', 'ca', 'bc'] {n} n代表个数 a-z中的任意两个
# ['ab', 'ca', 'bc'] import re
# print(re.findall('\w','ab 12\+-*&_')) #['a', 'b', '1', '2', '_']
# print(re.findall('\W','ab 12\+-*&_')) # [' ', '\\', '+', '-', '*', '&']
# print(re.findall('\S','ab\r1\n2\t\+-*&_')) #非空字符串
# ['a', 'b', '1', '2', '\\', '+', '-', '*', '&', '_']
# print(re.findall('\s','ab\r1\n2\t\+-*&_')) #匹配任意空字符串['\r', '\n', '\t']
# print(re.findall('\d','ab\r1\n2\t\+-*&_')) #['1', '2']
# print(re.findall('\D','ab\r1\n2\t\+-*&_')) #任意非数字
# ['a', 'b', '\r', '\n', '\t', '\\', '+', '-', '*', '&', '_']
# print(re.findall('\w_sb','egon alex_sb123123wxx_sb,lxx_sb')) # 字母数字下划线 ['x_sb', 'x_sb', 'x_sb']
# print(re.findall('\Aalex','abcalex is salexb')) # 匹配字符串开始 []
# print(re.findall('\Aalex','alex is salexb')) #匹配字符串开始 ['alex']
# print(re.findall('^alex','alex is salexb')) #匹配字符串的开头 ['alex']
# print(re.findall('sb\Z','alexsb is sblalexbsb')) #匹配字符串结束,如果是存在换行,只匹配到换行前的结束字符串['sb']
# print(re.findall('sb$','alexsb is sbalexbsb')) # 匹配字符串末尾['sb']
# print(re.findall('^ebn$','ebn1')) #匹配开头 匹配结尾[]
# print(re.findall('a\nc','a\nc a\tc alc')) #['a\nc'] # 重复匹配
# . ? * + {m,n} .* .*?
# 1 . 代表除了换行符外的任意一个字符
# print(re.findall('a.c','abc alc aAc aaaaa\nc')) #['abc', 'alc', 'aAc']
# print(re.findall('a.c','abc alc aAc aaaaca\nc',re.DOTALL))
# ['abc', 'alc', 'aAc', 'aac', 'a\nc']
# 2 ? 代表左边那一个字符重复0次或1次
# print(re.findall('ab?','a ab abb abbb abbbbb')) #['a', 'ab', 'ab', 'ab', 'ab']
# 3 * 代表左边那一个字符出席那0次或无穷次
# print(re.findall('ab*','a ab abb abbb abbbb')) #['a', 'ab', 'abb', 'abbb', 'abbbb']
# 4 + 代表左边那一个字符出现1次或无穷次
# print(re.findall('ab+','a ab abb abbba abbbbb')) #['ab', 'abb', 'abbb', 'abbbbb']
# 5 {m,n}:代表左边那一个字符出现m次到n次
# print(re.findall('ab?','a ab abb abbbbb ')) #['a', 'ab', 'ab', 'ab']
# print(re.findall('ab{0,1}','a ab abb abbbbb ')) #['a', 'ab', 'ab', 'ab'] # print(re.findall('ab*','a ab abb abbb abbb abbbbb'))
# ['a', 'ab', 'abb', 'abbb', 'abbb', 'abbbbb']
# print(re.findall('ab{0,}','a ab abb abbb abbb abbbbb'))
# ['a', 'ab', 'abb', 'abbb', 'abbb', 'abbbbb'] # print(re.findall('ab+','a ab abb abbbb abbbb'))
# ['ab', 'abb', 'abbbb', 'abbbb']
# print(re.findall('ab{1,}','a ab abb abbbb abbbb'))
# ['ab', 'abb', 'abbbb', 'abbbb'] # print(re.findall('ab{1,3}','a ab abb abbb abbbbbb'))
# ['ab', 'abb', 'abbb', 'abbb'] # 6 .* 匹配任意长度, 任意的字符 =>贪婪匹配
# print(re.findall('a.*c','ac a123c aaaac a*123)()c asdfdffdf'))
# ['ac a123c aaaac a*123)()c'] # 7 .*? :非贪婪匹配 {0,1}最少为零个中间值
# print(re.findall('a.*?c',' ac a123c456c')) #['a123c'] # ():分组
# print(re.findall('(alex_sb)','alex_sb asdfgdsfdsfh_sb'))
# ['alex'] 只返回匹配到的括号内的内容
# print(re.findall(
# 'herf="(.*?)"',
# '<li><a id="blog_nav_sitehome" class="menu" href="http://www.cnblogs.com/">博客园</a></li>'
# ))
# [] 最少0个 # []:匹配一个指定返回内的字符(这一个字符来自于括号内定义的)
# print(re.findall('a[0-9][0-9]c','alc a+c a2c a9c allc a-c acc aAc'))
# []
# 当需要被当众普通符号匹配时,只嗯能放到[]的最左边或最右边
import re # print(re.findall('a[- + *]c', 'alc a+c a2c a9c a*c allc a-c acc aAc'))
# ['a+c', 'a*c', 'a-c']
# print(re.findall('a[a-zA-Z]c','alc a+c a2c a9c a*c allc a-c acc aAc'))
# ['alc', 'acc', 'aAc']
# []内的^代表取反的意思
# print(re.findall('a[^a-zA-Z]c','alc a+c a2C a9c a*c allc a-c acc aAc'))
# ['a+c', 'a9c', 'a*c', 'a-c']
# print(re.findall('a[^0-9]c','a c alc a+c a2c a9c a*c allc a-c acc aAc'))
# ['a c', 'alc', 'a+c', 'a*c', 'a-c', 'acc', 'aAc']
# print(re.findall('([a-z]+)_sb','egon alex_sb123njjkjkjkjk_sb,lxx_sb'))
# ['alex', 'njjkjkjkjk', 'lxx'] # |: 或者
# print(re.findall('compan(ies|y)','Too many companies have gone bankrupt,and the next one is my company'))
# ['ies', 'y']
# (?:) 代表取匹配成功的所有内容,而不是仅仅只是括号内的内容
# print(re.findall('compan(?:ies|y)','Too many companies have gone bankrupt,and the next one is my company'))
# ['companies', 'company']
# print(re.findall('alex|sb','alex sb sb asjkjkjkgon alex sb egon'))
# ['alex', 'sb', 'sb', 'alex', 'sb'] # re模块的其他方法:
# print(re.findall('alex|sb','123123 alex sb sfjdkklkgon alex sb egon '))
# print(re.search('alex|sb','123123 alex sb sfjdkklkgon alex sb egon ').group())
# print(re.search('^alex','123123 alex sb sfjdkklkgon alex sb egon '))
# ['alex', 'sb', 'alex', 'sb'] 找所有的
# alex search 从左往右找到第一个就停下
# None 从头开始匹配 不满足 # print(re.search('^alex', 'alex sb sadfsadfasdfegon alex sb egon').group())
# print(re.match('alex', '1alex sb sadfsadfasdfegon alex sb egon'))
# alex 从头找 找到一个结束
# None 相当于search的从头开始匹配 不满足
# print(re.match('alex', 'alex sb sadfsadfasdfegon alex sb egon').group())
# print(re.match('alex', 'alex sb sadfsadfasdfegon alex sb egon'))
# alex 从头开始匹配 满足 group取值
# <re.Match object; span=(0, 4), match='alex'> 从头开始匹配 满足
# print(re.match('alex', '123213 alex sb sadfsadfasdfegon alex sb egon'))
# None # info='a:b:c:d'
# print(info.split(':'))
# print(re.split(':',info))
# ['a', 'b', 'c', 'd']
# ['a', 'b', 'c', 'd'] # info =r'get :a.txt\3333/rwx'
# print(re.split('[:\\\/]',info))
# ['get ', 'a.txt', '3333', 'rwx'] # print('egon is beutifull egon'.replace('egon','EGON',1))
# EGON is beutifull egon
# print(re.sub('(.*?)(egon)(.*?)(egon)(.*?)',r'\1\2\3EGON\5','123 egon is beauifull egon 123'))
# (123 )(egon)( is beutifull )(egon)( 123)
# 123 egon is beauifull EGON 123 # \1\2\3EGON\5
# print(re.sub('(lqz)(.*?)(SB)',r'\3\2\1','lqz is SB'))
# SB is lqz # print(re.sub('([a-zA-Z)]+)([^a-zA-Z]+)([a-zA-Z]+)([^a-zA-Z]+)([a-zA-Z]+)',r'\5\2\3\4\1',r'lqzzzzz123+ is SB'))
# SB123+ is lqzzzzz # pattern =re.compile('alex')
# print(pattern.findall('alex is alex alex'))
# print(pattern.search('alex is alex alex').group())
# print(pattern.match('alex is alex alex').group())
# print(pattern.findall('alexfjksdjgkjskdfj is alex alex'))
# ['alex', 'alex', 'alex']
# alex
# alex
# ['alex', 'alex', 'alex']

操作分组的方法

(?P<name>...):有名分组

返回值是math匹配的结果对象,可以 .group(组序号|组名)来取具体组的信息

res=re.match('(\d{3})(?P<center>\d{3})(\d{3})','123456789)

print(res.group('center'))

456

# print(re.findall('\d*', '<123456789>'))
# ['', '123456789', '', ''] #先匹配< 后匹配123456789 在匹配> 最后匹配整体
# 1、书写可以配身份证的正则表达式
# 身份证:18位 由17位数字本体码和1位校验码组成排列顺序从左至右依次为:
# 六位数字地址码,八位数字出生日期码,三位数字顺序码和一位数字校验码。 # [1-7][0-9]{5} #六位数字地址码
# (?:19[0-9]{2}|20[01][0-9]) # 1900-2019
# (?:0[0-9]|1[12]) #01-12 月
# (?:0[0-9]|[12][0-9]|3[01]) #01-31 天
# [0-9]{3} #三为数字顺序码
# [0-9Xx] #一位验证码
# [1-7][0-9]{5}(?:19[0-9]{2}|20[01][0-9])(?:0[0-9]|1[12])(?:0[0-9]|[12][0-9]|3[01])[0-9]{3}[0-9Xx] # 2 书写可以匹配邮箱的正则表达式
# 2530302605@qq.com \.转义点把它当成普通的.匹配
# [a-zA-Z0-9]\w{,15}@[176|178|192]\.[com|com\.cn|cn] # 获取百度首页图片地址
import re
import requests
responds=requests.get('http://www.baidu.com/')
print(responds)
content=responds.text
# print(content)
content+='http://www.baidu.com/wimg/gs.gif'
res1_list=re.findall('www[^w]*?(?:gif|png)',content)
print(res1_list)
# ['www.baidu.com/img/bd_logo1.png', 'www.baidu.com/bdorz/login.gif', 'www.baidu.com/bdorz/login.gif', 'www.baidu.com/img/gs.gif']
res_list=re.findall('www.{1,30}(?:gif|png)',content)
print(res_list)
# ['www.baidu.com/img/bd_logo1.png', 'www.baidu.com/bdorz/login.gif', 'www.baidu.com/bdorz/login.gif', 'www.baidu.com/img/gs.gif', 'www.baidu.com/wimg/gs.gif']
#

小练习

内存管理 re模块的更多相关文章

  1. Linux内存管理 (11)page引用计数

    专题:Linux内存管理专题 关键词:struct page._count._mapcount.PG_locked/PG_referenced/PG_active/PG_dirty等. Linux的内 ...

  2. rt-thread中动态内存分配之小内存管理模块方法的一点理解

    @2019-01-18 [小记] rt-thread中动态内存分配之小内存管理模块方法的一点理解 > 内存初始化后的布局示意 lfree指向内存空闲区首地址 /** * @ingroup Sys ...

  3. 内存管理与正则(re)模块

    内存管理 垃圾回收机制 不能被程序访问到的数据,就称之为垃圾 也就是失去了一个能够访问到值数据的名称空间,导致在内存中无作为 引用计数:是内存管理的原理 引用计数是用来记录值的内存地址被记录的次数 每 ...

  4. 一个C语言内存管理模块的实现

    C 内存管理模块的编写 C语言手动管理内存很困难,有时候很难发现内存泄漏,这两天看了一下里面有写了一个简单的内存管理模块,发现挺精巧,可以有效检测内存泄漏 原理很简单,就是把C的malloc函数分配的 ...

  5. python基础——16(re模块,内存管理)

    一.内存管理 1.垃圾回收机制 不能被程序访问到的数据,就称之为垃圾. 1.1.引用计数 引用计数是用来记录值的内存地址被记录的次数的. 每一次对值地址的引用都使该值的引用计数+1:每一次对值地址的释 ...

  6. PHP扩展-生命周期和内存管理

    1. PHP源码结构 PHP的内核子系统有两个,ZE(Zend Engine)和PHP Core.ZE负责将PHP脚本解析成机器码(也成为token符)后,在进程空间执行这些机器码:ZE还负责内存管理 ...

  7. Python深入06 Python的内存管理

    作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 语言的内存管理是语言设计的一个重要方面.它是决定语言性能的重要因素.无论是C语言的 ...

  8. iOS经典面试题总结--内存管理

    iOS经典面试题总结--内存管理 内存管理 1.什么是ARC? ARC是automatic reference counting自动引用计数,在程序编译时自动加入retain/release.在对象被 ...

  9. DPDK内存管理(1)

    1 前言 DPDK将利用hugepage预留的物理内存统一的组织管理起来,然后以库的方式对外提供使用的接口.下图展示了DPDK中内存有关的模块的相互关系. rte_eal            是统一 ...

随机推荐

  1. Idea快捷键和使用技巧【未完】

    参考1:点击跳转 参考2:点击跳转2 整合后的如下所示:

  2. Java常用类库 读书笔记 二

    1.Date类 常用操作方法: public Date ()                         构造方法,实例化Date类对象 public Data(long Date)       ...

  3. java.text.DateFormat 线程不安全问题

    java.text下的 DateFormat 是线程不安全的: 建议1: 1.使用threadLocal包装DateFormat(太复杂,不推荐) 2.使用org.apache.commons.lan ...

  4. Multi-Projector Based Display Code ---- ModelViewer

    Overview Model viewer is another application we provided for large display. It is designed for viewi ...

  5. 数据结构优化dp

    本以为自己的dp已经成熟了没想到在优化上面还是欠佳 或者是思路方面优化dp还不太行. 赤壁之战 当然 很有意思的题目描述 大体上是苦肉计吧 .盖黄 ... 题意是 求出长度为m的严格上升子序列的个数 ...

  6. composer相关使用

    #composer安装 curl -sS https://getcomposer.org/installer | php #如果该命令执行不了,通过其他方式下载install文件后再执行“php in ...

  7. oracle学习笔记第一天

    oracle学习笔记第一天 --oracle学习的第一天 --一.几个基础的关键字   1.select select (挑选) 挑选出显示的--列--(可以多列,用“,”隔开,*表示所有列),为一条 ...

  8. Exception in thread "main" java.lang.UnsupportedClassVersionError: org/apache/maven/cli/MavenCli : Unsupported major.minor version 51.0

    原因:JDK版本不兼容.运行的Java Class文件采用高版本的JDK编译,然后在低版本的JRE环境中运行,有时会报此错误. 解决:1)升级JDK 2)调整Eclipse中Java Compiler ...

  9. Byword for Mac(Markdown编辑器)中文版

    还在找Markdown编辑器吗?那不妨试试Byword for Mac吧!这是一款轻量级的富文本编辑器,byword mac版提供了完整的Markdown支持,包含脚注.表格.交叉引用等功能,Bywo ...

  10. 使用TCP通信文件上传

    客服端读取本地文件,吧文件上传到服务器,服务器在吧上传的文件保存到服务器硬盘上方法分析1:客户端使用本地字节输入流读取要上传的文件 2:客户端使用网络字节输出流,吧读取到的文件上传到服务器 3:服务器 ...