热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

六、python常用模块和正则表达式

一、模块1.import模块的实质就是把要导入模块里面的代码,从上到下执行一遍,找模块的顺序是,先从当前目录下找,找不到的话

一、模块

1.import模块的实质就是把要导入模块里面的代码,从上到下执行一遍,找模块的顺序是,先从当前目录下找,找不到的话,在环境变量里面找
2.模块标准
A:标准模块:
python自带的,不需要安装的,直接import就能用的
B:自己写的模块:
就是自己写的python
C:第三方模块:
别人已经开发好的模块,需要安装的
a:安装方式第一种:
这是操作系统命令,不是在python命令行执行
pip install **** #这是安装一个模块
pip list 查看自己所安装的模块
pip uninstall *** 卸载模块
pip这个模块在python3里面是python自带的,安装完python就能直接用,但是在python2里面没有这个模块,需要你手动安装才能用
easy_install requests 跟pip差不多 可以直接安装,这个也是傻瓜式的

b:第二种方法,手动安装:
1.先下载安装包,直接百度搜例如:python requests模块
2.解压安装包
3.在解压的目录下执行python setup.py install
3.OS模块
清日志脚本
1.创建一个vi clean_log.py脚本
import os
file_list = os.listdir('.')
for file in file_list:
if 'gz' in file:
os.remove(file)
2.然后在该目录下执行此脚本:python3 clean_log.py
3.如果要定时清理日志的话,把它加入到crontab -e里面定时清理
 #crontab -e
  10(分) 21(时) *** python xxx/clean_log.py#即21:10定时执行clean_log.py日志


import os
#常用的
print(os.getcwd())#取当前工作目录
print(os.chdir(r"/Users/yidao/PycharmProjects/byzywq/day5"))#更改当前目录
print(os.mkdir("test1"))#创建文件夹,只能在当前目录创建
print(os.makedirs(r"day7\test1"))#递归创建文件夹,父目录不存在时创建父目录
# print(os.removedirs(r"test1\test2"))#递归删除空目录
# print(os.rmdir("test1"))#删除指定的文件夹,只能删除空文件夹
print(os.remove(r"E:\byz_code\day4\a.txt"))#删除文件,如果要删除其他文件夹下文件加绝对路径
# os.rename("test","test1")#重命名
# print(os.sep)#当前操作系统的路径分隔符
print(__file__)#代表当前文件
print(os.path.abspath('bb.py'))#获取绝对路径
print(os.path.dirname)#获取父目录
print(os.path.dirname(os.path.dirname(__file__)))#获取父目录
print(os.path.exists("/usr/local"))#目录/文件是否存在,返回true或者false
print(os.path.isfile("bb.py"))#判断是否是一个文件
print(os.path.isdir("/usr/local"))#是否是一个路径
print(os.path.join("root",'hehe','haha','a.log'))
print(os.chmod("/usr/local",7))#给文件/目录加权限,7是最高权限,还有421
  windows下\r\n是换行符,Linux下\n是换行符



不常用的
print(os.curdir)#当前目录
print(os.pardir)#父目录
print(os.listdir('.'))#列出一个目录下的所有文件,.代表当前目录
os.rename("test","test1")#重命名
print(os.stat("len_os.py"))#获取文件信息
print(os.linesep)#当前操作系统的换行符
print(os.pathsep)#当前系统的环境变量中每个路径的分隔符,linux是:,windows是;
print(os.environ)#当前系统的环境变量  
sys.path只是针对python有用的环境变量  
print(os.name)#当前系统名称
print(os.path.split("/usr/hehe/hehe.txt"))#分割路径和文件名print(os.path.basename("/usr/local"))#获取最后一级,如果是文件显示文件名,如果是目录显示目录

print(os.path.isabs("."))#判断是否是绝对路径
print(os.path.isfile("/usr/local"))#判断是否是一个文件
print(os.path.isdir("/usr/local"))#是否是一个路径
print(os.path.join("/root",'hehe','a.sql'))#拼接成一个路径
print(os.path.getatime("len_os.py"))#输出最近访问时间

4.sys模块
import sys
sys.argv#命令行参数List,第一个元素是程序本身路径
sys.exit(n)#退出程序,正常退出时exit(0)
print(sys.version)#获取Python解释程序的版本信息
sys.maxint#最大的Int值
sys.path#返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值
print(sys.platform)#返回操作系统平台名称
sys.stdout.write('please:') # 向屏幕输出一句话
val = sys.stdin.readline()[:-1] # 获取输入的值
if __name__=='__main__':#只有在运行自己这个python文件的时候
#才会执行下面的代码,在别的模块里面导入的时候是不会执行的
print('这是在自己文件里面的时候:',__name__)
sayHi('wmh') # 我自测的时候调用

5.time模块
时间、日期操作
import datetime,time
一种是时间戳、一种是格式化时间、一种是时间元组
常用的:

  print(time.sleep(10))#休息几s

  print(time.strftime("%y-%m-%d %H:%M:%S"))#将时间元组转换成格式化输出的字符串,%y年,%m月,%d日,%H时,%M分,%S秒

  print(datetime.datetime.now()+datetime.timedelta(3))#3天后的时间
  print(datetime.datetime.now()+datetime.timedelta(-3))#3天前的时间

不常用:

print(time.timezone)#和标准时间相差的时间,单位是s
print(int(time.time()))#获取当前时间戳
时间戳的意思就是从unix元年(1970.1.1),到现在的秒数
格式化好的时间 2017.6.18 14:30:30
print(time.gmtime(1497767612))#把时间戳转换成时间元组,如果不传的话,默认取标准时区的时间戳,utc时区
print(time.localtime())#把时间戳转换成时间元组,如果不传的话,默认取当前时区的时间戳,标准时区
print(time.mktime(time.localtime()))#把时间元组转换成时间戳
print(time.strptime("20160204 191919","%Y%m%d %H%M%S"))#将格式化的时间转换成时间元组
print(time.struct_time)#时间元组
print(time.asctime())#时间元组转换成格式化时间
print(time.ctime())#时间戳转换成格式化时间
print(datetime.datetime.now())#当前时间格式化输出


6.打开一个网站
import requests
a、打开博客 requests.get
b、从返回的html里面找到文章的超链接地址 正则表达式匹配
c、打开文章的超链接 requests.get
d、保存到本地 写文件
url = 'http://szz.nnzhp.cn/'
req = requests.get(url)
print(req.text)#获取返回的内容
print(req.encoding)#获取网站的编码

二.软件开发规范

bin里面放入口,core里面放主逻辑,conf写配置文件,data目录放一些数据

'''

def sayHi(name):

  print('Hi~ %s'%name) 

if __name__ =='__main__':#只有在运行自己这个Python文件的时候才会执行这个代码,在别的模块导入的时候是不会执行这个代码

  print('这是在自己文件里面的时候',__name__)

  sayHi('wmd')#自测时调用

'''

'''
http://www.jianshu.com/p/1e402922ee32/ markdown语法看这个
'''
三.正则表达式

1.正则表达式就是用来查找字符串的,他能查找规则比较复杂的字符串
一、re模块
import re
s = 'besttest is is is is good'
A:match方法
print(re.match(r'be',s).group())
a.字符串前面加'r'代表原字符串
b.match方法接收3个参数,第一个是匹配的规则,也就是正则表达式,第二个是要查找的字符串,第三个参数不是必填的,用于控制正则表达式的匹配方式,看下面正则表达式的匹配模式。是从字符串的第一个单词中匹配字符串,如果匹配到返回一个对象,如果匹配不到,则返回None
#>>><_sre.SRE_Match object; span&#61;(0, 4), match&#61;&#39;best&#39;>
B&#xff1a;search方法
print(re.search(r&#39;is&#39;,s))
search方法的参数和match一样&#xff0c;和match方法不一样的是&#xff0c;match是从字符串里面的第一个单词里面找&#xff0c;而search方法则是从字符串的整个内容里面找&#xff0c;如果找到了就返回第一个&#xff0c;找不到就返回None
>>> <_sre.SRE_Match object; span&#61;(0, 4), match&#61;&#39;best&#39;>
C:findall方法
print(re.findall(r&#39;is&#39;,s))
findall方法的参数上面的match、search一样&#xff0c;和他们不一样的是&#xff0c;findall会返回所有一个list&#xff0c;把所有匹配到的字符串&#xff0c;放到这个list里面&#xff0c;如果找不到的话&#xff0c;就返回一个空的list
>>> [&#39;best&#39;]
D:sub方法
print(re.sub(r&#39;best&#39;,&#39;Best&#39;,s))
#sub方法和字符串的replace方法一样&#xff0c;是用来替换字符串的&#xff0c;把匹配到的值替换成一个新的字符串&#xff0c;接收3个参数&#xff0c;第一个是正则表达式&#xff0c;第二个是要替换成什么&#xff0c;第三个就是要查找的字符串&#xff0c;会返回一个新的字符串&#xff0c;如果匹配不到的话&#xff0c;返回原来的字符串
#>>> Besttest is good
print(re.split(&#39;best&#39;,s))
#split 方法和字符串的split方法一样&#xff0c;是用来分割字符的&#xff0c;按照匹配到的字符串进行分割&#xff0c;返回的是一个list&#xff0c;如果匹配不到的话&#xff0c;那返回的list中还是原来的字符串
#>>> [&#39;&#39;, &#39;test is good&#39;]

二、常用正则表达式符号
1.数量词
s &#61; &#39;besttest is good&#39;
&#39;*&#39; 匹配*号前的字符0次或多次&#xff0c;只是*前面的一个字符
print(re.findall(r&#39;r*&#39;,&#39;besttest very good&#39;))
>>> [&#39;be&#39;]
&#39;&#43;&#39; 匹配前一个字符1次或多次&#xff0c;只是&#43;前面的一个字符
print(re.findall(r&#39;st&#43;&#39;,&#39;besttest is best&#39;))
>>> [&#39;stt&#39;, &#39;st&#39;, &#39;st&#39;]
&#39;?&#39; 匹配前一个字符1次或0次,只是?前面的一个字符
print(re.findall(r&#39;st?&#39;,&#39;besttest is best&#39;))
&#39;{m}&#39; 匹配前一个字符m次
print(re.findall(r&#39;t{2}er&#39;,&#39;besttest is best letter&#39;))
>>> [&#39;tt&#39;]
&#39;{n,m}&#39; 匹配前一个字符n到m次
print(re.findall(r&#39;t{2,3}&#39;,&#39;besttest is best&#39;))
>>> [&#39;tt&#39;, &#39;t&#39;, &#39;t&#39;]
&#39;.&#39;代表任意一个字符

2.一般字符
&#39;.&#39; 默认匹配除\n之外的任意一个字符
print(re.findall(r&#39;b.&#39;,&#39;besttest is good&#39;))
&#39;[....]&#39;,字符集合&#xff0c;
>>> [&#39;be&#39;]
>>> [&#39;st&#39;, &#39;st&#39;, &#39;s&#39;, &#39;st&#39;]
&#39;\&#39; 转译符&#xff0c;前面的* &#43; ?这样的字符都有特殊含义了&#xff0c;如果你想就想找它的话&#xff0c;那就得转译了
意思就是说如果你想让特殊字符失去以前的含义&#xff0c;那么就得给它前面加上\
print(re.findall(r&#39;\?&#39;,&#39;besttest is best????&#39;))
>>> [&#39;?&#39;, &#39;?&#39;, &#39;?&#39;, &#39;?&#39;]
&#39;|&#39; 匹配|左或|右的字符
print(re.findall(r&#39;best|is&#39;,&#39;besttest is best&#39;))
>>> [&#39;best&#39;, &#39;is&#39;, &#39;best&#39;]
&#39;[]&#39; 字符集合&#xff0c;某些字符的集合&#xff0c;匹配的时候是这个集合里面的任意一个就行
print(re.findall(r&#39;be[stacj]&#39;,&#39;besttest is best bejson&#39;))
>>>[&#39;bes&#39;, &#39;bes&#39;, &#39;bej&#39;]
在[]里面如果用^的话代表取反&#xff0c;也就是不包括的这些字符串的
print(re.findall(r&#39;be[^stac]&#39;,&#39;besttest is best bejson&#39;))

3.边界匹配

&#39;^&#39; 匹配以什么字符开头,多行情况下匹配每一行的开头
print(re.findall(r&#39;^b&#39;,&#39;besttest is good best&#39;))
>>> [&#39;b&#39;]
print(re.findall(r&#39;^b&#39;,&#39;besttest is good\nbest&#39;,re.M))#多行模式
>>> [&#39;b&#39;,&#39;b&#39;]
&#39;$&#39; 匹配以什么字符结尾,多行情况下匹配每一行的结尾
print(re.findall(r&#39;jpge$|png$|png$&#39;,&#39;touxiang.png&#39;))
>>> [&#39;d&#39;]
print(re.findall(r&#39;d$&#39;,&#39;besttest is good\nbest is good&#39;,re.M))#多行模式
>>>[&#39;d&#39;,&#39;d&#39;]
&#39;\A&#39; 仅以什么字符开头&#xff0c;和^不同的是它不能用多行模式
print(re.findall(r&#39;\Ahttp&#39;,&#39;http://www.baidu.com is good\nhttp://www.souhu.com&#39;))
>>> [&#39;b&#39;]
&#39;\Z&#39; 仅以什么字符结尾&#xff0c;和$不同的是它不能用多行模式
print(re.findall(r&#39;.jpge\Z|.png\Z|.gif\Z&#39;,&#39;touxiang.png\nqq.gif&#39;,re.M))
>>> [&#39;d&#39;]
4.预定义字符集合

&#39;\d&#39; 匹配数字0-9&#xff0c;&#43;表示出现1次或多次
print(re.findall(r&#39;\d&#43;&#39;,&#39;sdf2342312sdfs2342342f&#39;))
>>> [&#39;2342312&#39;, &#39;2342342&#39;]
&#39;\D&#39; 匹配非数字
print(re.findall(r&#39;\D&#39;,&#39;sdf2342312sdfs&#39;))
>>>[&#39;s&#39;, &#39;d&#39;, &#39;f&#39;, &#39;s&#39;, &#39;d&#39;, &#39;f&#39;, &#39;s&#39;]
&#39;\w&#39; 匹配[A-Za-z0-9],也就是所有的字母和数字和中文
print(re.findall(r&#39;\w&#43;&#39;,&#39;sdf234%^2312sdfs&你好&#39;))
>>>[&#39;sdf234&#39;, &#39;2312sdfs&#39;, &#39;你好&#39;]
&#39;\W&#39; 匹配不是[A-Za-z0-9]&#xff0c;也就是不是字母和数字
print(re.findall(r&#39;\W&#39;,&#39;sdf234%^2312sdfs&你好&#39;))
>>>[&#39;%&#39;, &#39;^&#39;, &#39;&&#39;]
&#39;\s&#39; 匹配空白字符、\t、\n、\r,空格
print(re.findall(&#39;\s&#39;,&#39;axss\n\tsdf\t\r\t sds 2323&#39;))
>>> [&#39;\n&#39;, &#39;\t&#39;, &#39;\t&#39;, &#39;\r&#39;, &#39;\t&#39;, &#39; &#39;, &#39; &#39;]
&#39;\S&#39;匹配空白字符,不是\t、\n、\r,空格
print(re.findall(&#39;\s&#39;,&#39;axss\n\tsdf\t\r\t&#39;))
>>>[&#39;\n&#39;, &#39;\t&#39;, &#39;\t&#39;, &#39;\r&#39;, &#39;\t&#39;]
print(re.findall(r&#39;ab[A-e]&#39;,&#39;abc abd abe abf&#39;))
[A-z]表示所有的大小写字母
[a-z]表示所有的小写字母
[A-Z]表示所有的大些字母
[0-9]表示所有的数字
import string,random
# sub_str &#61; string.ascii_letters&#43;string.digits
# new_str &#61; &#39;&#39;.join(random.sample(sub_str,8))
# print(&#39;new_str:&#39;,new_str)
# print(re.findall(r&#39;[A-Z]&#39;,new_str))
# print(re.findall(r&#39;[a-z]&#39;,new_str))
# print(re.findall(r&#39;[0-9]&#39;,new_str))
# if re.findall(r&#39;[A-Z]&#39;,new_str) and re.findall(r&#39;[a-z]&#39;,new_str) and re.findall(r&#39;[0-9]&#39;,new_str):
# print(new_str)

#匹配包含大小写字母和数字
sub_str &#61; string.ascii_letters &#43; string.digits
fw &#61; open(&#39;passwd&#39;,&#39;w&#39;)
def passwds(num):
count &#61; 0
while count
new_str &#61; &#39;&#39;.join(random.sample(sub_str, 8))
if re.search(r&#39;[A-Z]&&#39;, new_str) and \
re.search(r&#39;[a-z]&#39;, new_str) and \
re.search(r&#39;[0-9]&#39;, new_str):
fw.write(new_str&#43;&#39;\n&#39;)
count&#43;&#61;1
passwds(100)
5.分组匹配
&#39;(...)&#39; 分组匹配&#xff0c;把某些规则写成在一个组里&#xff0c;这样就可以直接对这个进行一些匹配了&#xff0c;举个例子的话&#xff0c;如果要匹配ip地址的话
ip地址是类似这样的192.168.5.1&#xff0c;每一位都是1位或者3位的数字然后后面有个点正常写的话,得这么写
print(re.findall(r&#39;\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}&#39;,"192.168.1.3"))
>>> [&#39;192.168.1.3&#39;]
这样写的话&#xff0c;有点麻烦了&#xff0c;通过上面的我们可以发现规律&#xff0c;除了第一个后面的全都是&#39;.\d{1,3}&#39;&#xff0c;写重复的代码就是低级的&#xff0c;这样的话就可以用分组了
就把&#39;.\d{1,3}&#39;当做一个整体&#xff0c;然后让他们出现3次就ok了&#xff0c;可以改成下面这样的
print(re.search(r&#39;\d{1,3}(.\d{1,3}){3}&#39;,"192.168.1.3").group())#这个是用search方法的&#xff0c;结果和上面的一样的
>>> 192.168.1.3
print(re.findall(r&#39;\d{1,3}(.\d{1,3}){3}&#39;,"192.168.1.3"))#咱们继续用findall方法&#xff0c;发现结果是下面的
>>> [&#39;.3&#39;]
为啥会这样呢&#xff0c;用match方法和search方法都是正常的&#xff0c;findall方法这里有个坑&#xff0c;就是如果findall方法里面有分组的话&#xff0c;默认就是分组里面的内容&#xff0c;那结果就只是分组里面的内容
&#xff0c;如果想让结果正确的话就在分组最前面写上&#39;?:&#39;&#xff0c;一个问号和一个冒号就好了&#xff0c;启用“不捕捉模式”
print(re.findall(r&#39;\d{1,3}(?:.\d{1,3}){3}&#39;,"192.168.1.3"))#这么写结果就对了

findall方法里面有分组的话&#xff0c;默认结果就只是分组里面的内容


import os
# print(os.makedirs(r"day7/test1"))#递归创建文件夹&#xff0c;父目录不存在时创建父目录
print(os.rmdir(r"day7"))

 六、补充知识点

1. __init__.py的作用

 

2.(.*)&#xff0c;(.?)贪婪模式&#xff0c;非贪婪模式

3.popen&#xff08;python调用Linux的方式os.system&#xff0c;os.popen&#xff09;

4.zip

 

转:https://www.cnblogs.com/ywqq/p/7066274.html



推荐阅读
  • 本文介绍了一种轻巧方便的工具——集算器,通过使用集算器可以将文本日志变成结构化数据,然后可以使用SQL式查询。集算器利用集算语言的优点,将日志内容结构化为数据表结构,SPL支持直接对结构化的文件进行SQL查询,不再需要安装配置第三方数据库软件。本文还详细介绍了具体的实施过程。 ... [详细]
  • 如何实现织梦DedeCms全站伪静态
    本文介绍了如何通过修改织梦DedeCms源代码来实现全站伪静态,以提高管理和SEO效果。全站伪静态可以避免重复URL的问题,同时通过使用mod_rewrite伪静态模块和.htaccess正则表达式,可以更好地适应搜索引擎的需求。文章还提到了一些相关的技术和工具,如Ubuntu、qt编程、tomcat端口、爬虫、php request根目录等。 ... [详细]
  • 本文详细介绍了SQL日志收缩的方法,包括截断日志和删除不需要的旧日志记录。通过备份日志和使用DBCC SHRINKFILE命令可以实现日志的收缩。同时,还介绍了截断日志的原理和注意事项,包括不能截断事务日志的活动部分和MinLSN的确定方法。通过本文的方法,可以有效减小逻辑日志的大小,提高数据库的性能。 ... [详细]
  • 本文介绍了lua语言中闭包的特性及其在模式匹配、日期处理、编译和模块化等方面的应用。lua中的闭包是严格遵循词法定界的第一类值,函数可以作为变量自由传递,也可以作为参数传递给其他函数。这些特性使得lua语言具有极大的灵活性,为程序开发带来了便利。 ... [详细]
  • 高质量SQL书写的30条建议
    本文提供了30条关于优化SQL的建议,包括避免使用select *,使用具体字段,以及使用limit 1等。这些建议是基于实际开发经验总结出来的,旨在帮助读者优化SQL查询。 ... [详细]
  • 本文讨论了在数据库打开和关闭状态下,重新命名或移动数据文件和日志文件的情况。针对性能和维护原因,需要将数据库文件移动到不同的磁盘上或重新分配到新的磁盘上的情况,以及在操作系统级别移动或重命名数据文件但未在数据库层进行重命名导致报错的情况。通过三个方面进行讨论。 ... [详细]
  • Python瓦片图下载、合并、绘图、标记的代码示例
    本文提供了Python瓦片图下载、合并、绘图、标记的代码示例,包括下载代码、多线程下载、图像处理等功能。通过参考geoserver,使用PIL、cv2、numpy、gdal、osr等库实现了瓦片图的下载、合并、绘图和标记功能。代码示例详细介绍了各个功能的实现方法,供读者参考使用。 ... [详细]
  • MyBatis多表查询与动态SQL使用
    本文介绍了MyBatis多表查询与动态SQL的使用方法,包括一对一查询和一对多查询。同时还介绍了动态SQL的使用,包括if标签、trim标签、where标签、set标签和foreach标签的用法。文章还提供了相关的配置信息和示例代码。 ... [详细]
  • 本文介绍了django中视图函数的使用方法,包括如何接收Web请求并返回Web响应,以及如何处理GET请求和POST请求。同时还介绍了urls.py和views.py文件的配置方式。 ... [详细]
  • 本文介绍了在处理不规则数据时如何使用Python自动提取文本中的时间日期,包括使用dateutil.parser模块统一日期字符串格式和使用datefinder模块提取日期。同时,还介绍了一段使用正则表达式的代码,可以支持中文日期和一些特殊的时间识别,例如'2012年12月12日'、'3小时前'、'在2012/12/13哈哈'等。 ... [详细]
  • 延迟注入工具(python)的SQL脚本
    本文介绍了一个延迟注入工具(python)的SQL脚本,包括使用urllib2、time、socket、threading、requests等模块实现延迟注入的方法。该工具可以通过构造特定的URL来进行注入测试,并通过延迟时间来判断注入是否成功。 ... [详细]
  • SpringMVC接收请求参数的方式总结
    本文总结了在SpringMVC开发中处理控制器参数的各种方式,包括处理使用@RequestParam注解的参数、MultipartFile类型参数和Simple类型参数的RequestParamMethodArgumentResolver,处理@RequestBody注解的参数的RequestResponseBodyMethodProcessor,以及PathVariableMapMethodArgumentResol等子类。 ... [详细]
  • 在Oracle11g以前版本中的的DataGuard物理备用数据库,可以以只读的方式打开数据库,但此时MediaRecovery利用日志进行数据同步的过 ... [详细]
  • 本文讨论了在VMWARE5.1的虚拟服务器Windows Server 2008R2上安装oracle 10g客户端时出现的问题,并提供了解决方法。错误日志显示了异常访问违例,通过分析日志中的问题帧,找到了解决问题的线索。文章详细介绍了解决方法,帮助读者顺利安装oracle 10g客户端。 ... [详细]
  • 背景应用安全领域,各类攻击长久以来都危害着互联网上的应用,在web应用安全风险中,各类注入、跨站等攻击仍然占据着较前的位置。WAF(Web应用防火墙)正是为防御和阻断这类攻击而存在 ... [详细]
author-avatar
溪谷小兵
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有