博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Python20-Day05
阅读量:4636 次
发布时间:2019-06-09

本文共 18769 字,大约阅读时间需要 62 分钟。

一、模块与包

  1、模块

  什么是模块?

  在python中,模块可以分为四个通用类别:

    1. 使用python编写的.py文件

    2. 已经被编译为共享库或DLL的c或者c++扩展

    3. 把一系列模块组织到一起的文件夹(注:文件夹下面有一个__init__.py文件,该文件夹称为包)

    4. 使用c编写并链接到python解释器的内置模块!

   为什么要使用模块?

  1、从文件级别组织程序,更方便管理

  2、拿来主义,提升开发效率

  以spam.py为例,来介绍模块的使用:文件名为spam.py  模块名:spam

#spam.pyprint('from the spam.py')money=1000def read1():    print('spam模块:',money)def read2():    print('spam模块')    read1()def change():    global money    money=0

  2、使用模块之import

  import的使用

  模块可以包含可执行的语句和函数的定义,为了初始化模块,只在模块名第一次遇到导入import语句时才执行。import语句是可以在程序中的任意位置使用的,且针对同一个模块可以import多次,为了防止重复导入,优化手段是:第一次导入就将模块名加载到内存中了,后续的import语句只是对已经加载到内存中的模块对象增加了一次引用,不会重复执行模块内的语句。

#test.pyimport spam #只在第一次导入时才执行spam.py内代码,此处的显式效果是只打印一次'from the spam.py',当然其他的顶级代码也都被执行了,只不过没有显示效果.import spamimport spamimport spam'''执行结果:from the spam.py'''

 

注:可以从sys.module中找到当前已经加载的模块,sys.module是一个字典,内部包含模块名与模块对象的映射,该字典决定了导入模块时是否需要重新导入。 

  在第一次导入模块时,会做三件事,重复导入会直接引用内存中已经加载好的结果

    1、 为源文件(spam模块)创建新的名称空间,在spam中定义的函数和方法若是使用到了global时访问的就是这个名称空间。

    2、在新创建的命名空间中执行模块中包含的代码,见初始导入import spam;函数定义也是被执行的语句,模块级别函数定义的执行将函数名放入模块全局名称空间,用globals()可以查看。

    3、创建名字spam来引用改命名空间。

  被导入的名称有独立的名称空间

    每个模块都是一个独立的名称空间,定义在这个模块中的函数,把这个模块的名称空间当做全局名称空间,这样在编写自己的模块时,就不用担心定义在自己模块中的全局变量会在被导入时,与使用者的全局变量冲突。

  为模块起别名:

    import spam as sm

  在一行中导入多个模块

    from spam import read1,read2

  3、使用模块之from ... import ...

  4、模块搜索路径

#模块的查找顺序1、在第一次导入某个模块时(比如spam),会先检查该模块是否已经被加载到内存中(当前执行文件的名称空间对应的内存),如果有则直接引用    ps:python解释器在启动时会自动加载一些模块到内存中,可以使用sys.modules查看2、如果没有,解释器则会查找同名的内建模块3、如果还没有找到就从sys.path给出的目录列表中依次寻找spam.py文件。#sys.path的初始化的值来自于:The directory containing the input script (or the current directory when no file is specified).PYTHONPATH (a list of directory names, with the same syntax as the shell variable PATH).The installation-dependent default.#需要特别注意的是:我们自定义的模块名不应该与系统内置模块重名。虽然每次都说,但是仍然会有人不停的犯错。 #在初始化后,python程序可以修改sys.path,路径放到前面的优先于标准库被加载。>>> import sys>>> sys.path.append('/a/b/c/d')>>> sys.path.insert(0,'/x/y/z') #排在前的目录,优先被搜索注意:搜索时按照sys.path中从左到右的顺序查找,位于前的优先被查找,sys.path中还可能包含.zip归档文件和.egg文件,python会把.zip归档文件当成一个目录去处理,#首先制作归档文件:zip module.zip foo.py bar.py import syssys.path.append('module.zip')import foo,bar#也可以使用zip中目录结构的具体位置sys.path.append('module.zip/lib/python')#windows下的路径不加r开头,会语法错误sys.path.insert(0,r'C:\Users\Administrator\PycharmProjects\a') #至于.egg文件是由setuptools创建的包,这是按照第三方python库和扩展时使用的一种常见格式,.egg文件实际上只是添加了额外元数据(如版本号,依赖项等)的.zip文件。#需要强调的一点是:只能从.zip文件中导入.py,.pyc等文件。使用C编写的共享库和扩展块无法直接从.zip文件中加载(此时setuptools等打包系统有时能提供一种规避方法),且从.zip中加载文件不会创建.pyc或者.pyo文件,因此一定要事先创建他们,来避免加载模块是性能下降。

 

   5、包介绍

    什么是包?  

  1. 在python3中,即使包下没有__init__.py文件,import 包仍然不会报错,而在python2中,包下一定要有该文件,否则import 包报错  2. 创建包的目的不是为了运行,而是被导入使用,记住,包只是模块的一种形式而已,包的本质就是一种模块

    为什么要使用包?

包的本质就是一个文件夹,那么文件夹唯一的功能就是将文件组织起来随着功能越写越多,我们无法将所以功能都放到一个文件中,于是我们使用模块去组织功能,而随着模块越来越多,我们就需要用文件夹将模块文件组织起来,以此来提高程序的结构性和可维护性

 

 

6、 包的使用

1、示范文件

 

glance/ #Top-level package├── __init__.py #Initialize the glance package├── api #Subpackage for api│ ├── __init__.py│ ├── policy.py│ └── versions.py├── cmd #Subpackage for cmd│ ├── __init__.py│ └── manage.py└── db #Subpackage for db├── __init__.py└── models.py

 

#文件内容#policy.pydef get():print('from policy.py')#versions.pydef create_resource(conf):print('from version.py: ',conf)#manage.pydef main():print('from manage.py')#models.pydef register_models(engine):print('from models.py: ',engine)

 

执行文件与示范文件在同级目录下

2、包的使用之import

1 import glance.db.models2 glance.db.models.register_models('mysql') 单独导入包名称时不会导入包中所有包含的所有子模块,如#在与glance同级的test.py中import glanceglance.cmd.manage.main()'''执行结果:AttributeError: module 'glance' has no attribute 'cmd''''

 

解决方法:

1 #glance/__init__.py2 from . import cmd3 4 #glance/cmd/__init__.py5 from . import manage执行:1 #在于glance同级的test.py中2 import glance3 glance.cmd.manage.main()3、包的使用之from ... import ..

 

需要注意的是from后import导入的模块,必须是明确的一个不能带点,否则会有语法错误,如:from a import b.c是错误语法

1 from glance.db import models2 models.register_models('mysql')3 4 from glance.db.models import register_models5 register_models('mysql')4、from glance.api import *

 

在讲模块时,我们已经讨论过了从一个模块内导入所有*,此处我们研究从一个包导入所有*。

此处是想从包api中导入所有,实际上该语句只会导入包api下__init__.py文件中定义的名字,我们可以在这个文件中定义__all___:

 

1 #在__init__.py中定义2 x=103 4 def func():5 print('from api.__init.py')6 7 __all__=['x','func','policy']

 

此时我们在于glance同级的文件中执行from glance.api import *就导入__all__中的内容(versions仍然不能导入)。

#执行文件中的使用效果如下,请处理好包的导入from glance import *get()create_resource('a.conf')main()register_models('mysql')

 

5、绝对导入和相对导入

我们的最顶级包glance是写给别人用的,然后在glance包内部也会有彼此之间互相导入的需求,这时候就有绝对导入和相对导入两种方式:

绝对导入:以glance作为起始

相对导入:用.或者..的方式最为起始(只能在一个包中使用,不能用于不同目录内)

例如:我们在glance/api/version.py中想要导入glance/cmd/manage.py

 

1 在glance/api/version.py2 3 #绝对导入4 from glance.cmd import manage5 manage.main()6 7 #相对导入8 from ..cmd import manage9 manage.main()

 

测试结果:注意一定要在于glance同级的文件中测试

1 from glance.api import versions

6、包以及包所包含的模块都是用来被导入的,而不是被直接执行的。而环境变量都是以执行文件为准的

比如我们想在glance/api/versions.py中导入glance/api/policy.py,有的同学一抽这俩模块是在同一个目录下,十分开心的就去做了,它直接这么做

1 #在version.py中2 3 import policy4 policy.get()

没错,我们单独运行version.py是一点问题没有的,运行version.py的路径搜索就是从当前路径开始的,于是在导入policy时能在当前目录下找到

但是你想啊,你子包中的模块version.py极有可能是被一个glance包同一级别的其他文件导入,比如我们在于glance同级下的一个test.py文件中导入version.py,如下

 

1 from glance.api import versions2 3 '''4 执行结果:5 ImportError: No module named 'policy'6 '''7 8 '''9 分析:10 此时我们导入versions在versions.py中执行11 import policy需要找从sys.path也就是从当前目录找policy.py,12 这必然是找不到的13 '''

 

二、常用模块

logging模块

  日志级别

CRITICAL = 50 #FATAL = CRITICALERROR = 40WARNING = 30 #WARN = WARNINGINFO = 20DEBUG = 10NOTSET = 0 #不设置

  默认级别为warning,默认打印到终端

import logginglogging.debug('调试debug')logging.info('消息info')logging.warning('警告warn')logging.error('错误error')logging.critical('严重critical')'''WARNING:root:警告warnERROR:root:错误errorCRITICAL:root:严重critical'''

  为logging模块指定全局配置,针对所有logger有效,控制打印到文件中

  

复制代码可在logging.basicConfig()函数中通过具体参数来更改logging模块默认行为,可用参数有filename:用指定的文件名创建FiledHandler(后边会具体讲解handler的概念),这样日志会被存储在指定的文件中。filemode:文件打开方式,在指定了filename时使用这个参数,默认值为“a”还可指定为“w”。format:指定handler使用的日志显示格式。 datefmt:指定日期时间格式。 level:设置rootlogger(后边会讲解具体概念)的日志级别 stream:用指定的stream创建StreamHandler。可以指定输出到sys.stderr,sys.stdout或者文件,默认为sys.stderr。若同时列出了filename和stream两个参数,则stream参数会被忽略。#格式%(name)s:Logger的名字,并非用户名,详细查看%(levelno)s:数字形式的日志级别%(levelname)s:文本形式的日志级别%(pathname)s:调用日志输出函数的模块的完整路径名,可能没有%(filename)s:调用日志输出函数的模块的文件名%(module)s:调用日志输出函数的模块名%(funcName)s:调用日志输出函数的函数名%(lineno)d:调用日志输出函数的语句所在的代码行%(created)f:当前时间,用UNIX标准的表示时间的浮 点数表示%(relativeCreated)d:输出日志信息时的,自Logger创建以 来的毫秒数%(asctime)s:字符串形式的当前时间。默认格式是 “2003-07-08 16:49:45,896”。逗号后面的是毫秒%(thread)d:线程ID。可能没有%(threadName)s:线程名。可能没有%(process)d:进程ID。可能没有%(message)s:用户输出的消息

 

#======介绍可在logging.basicConfig()函数中可通过具体参数来更改logging模块默认行为,可用参数有filename:用指定的文件名创建FiledHandler(后边会具体讲解handler的概念),这样日志会被存储在指定的文件中。filemode:文件打开方式,在指定了filename时使用这个参数,默认值为“a”还可指定为“w”。format:指定handler使用的日志显示格式。datefmt:指定日期时间格式。level:设置rootlogger(后边会讲解具体概念)的日志级别stream:用指定的stream创建StreamHandler。可以指定输出到sys.stderr,sys.stdout或者文件,默认为sys.stderr。若同时列出了filename和stream两个参数,则stream参数会被忽略。format参数中可能用到的格式化串:%(name)s Logger的名字%(levelno)s 数字形式的日志级别%(levelname)s 文本形式的日志级别%(pathname)s 调用日志输出函数的模块的完整路径名,可能没有%(filename)s 调用日志输出函数的模块的文件名%(module)s 调用日志输出函数的模块名%(funcName)s 调用日志输出函数的函数名%(lineno)d 调用日志输出函数的语句所在的代码行%(created)f 当前时间,用UNIX标准的表示时间的浮 点数表示%(relativeCreated)d 输出日志信息时的,自Logger创建以 来的毫秒数%(asctime)s 字符串形式的当前时间。默认格式是 “2003-07-08 16:49:45,896”。逗号后面的是毫秒%(thread)d 线程ID。可能没有%(threadName)s 线程名。可能没有%(process)d 进程ID。可能没有%(message)s用户输出的消息#========使用import logginglogging.basicConfig(filename='access.log',                    format='%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s',                    datefmt='%Y-%m-%d %H:%M:%S %p',                    level=10)logging.debug('调试debug')logging.info('消息info')logging.warning('警告warn')logging.error('错误error')logging.critical('严重critical')#========结果access.log内容:2017-07-28 20:32:17 PM - root - DEBUG -test:  调试debug2017-07-28 20:32:17 PM - root - INFO -test:  消息info2017-07-28 20:32:17 PM - root - WARNING -test:  警告warn2017-07-28 20:32:17 PM - root - ERROR -test:  错误error2017-07-28 20:32:17 PM - root - CRITICAL -test:  严重criticalpart2: 可以为logging模块指定模块级的配置,即所有logger的配置

 

  4、logging模块的Formatter,Handler,Logger,Filter对象

#logger:产生日志的对象#Filter:过滤日志的对象#Handler:接收日志然后控制打印到不同的地方,FileHandler用来打印到文件中,StreamHandler用来打印到终端#Formatter对象:可以定制不同的日志格式对象,然后绑定给不同的Handler对象使用,以此来控制不同的Handler的日志格式

 

'''critical=50error =40warning =30info = 20debug =10'''import logging#1、logger对象:负责产生日志,然后交给Filter过滤,然后交给不同的Handler输出logger=logging.getLogger(__file__)#2、Filter对象:不常用,略#3、Handler对象:接收logger传来的日志,然后控制输出h1=logging.FileHandler('t1.log') #打印到文件h2=logging.FileHandler('t2.log') #打印到文件h3=logging.StreamHandler() #打印到终端#4、Formatter对象:日志格式formmater1=logging.Formatter('%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s',                    datefmt='%Y-%m-%d %H:%M:%S %p',)formmater2=logging.Formatter('%(asctime)s :  %(message)s',                    datefmt='%Y-%m-%d %H:%M:%S %p',)formmater3=logging.Formatter('%(name)s %(message)s',)#5、为Handler对象绑定格式h1.setFormatter(formmater1)h2.setFormatter(formmater2)h3.setFormatter(formmater3)#6、将Handler添加给logger并设置日志级别logger.addHandler(h1)logger.addHandler(h2)logger.addHandler(h3)logger.setLevel(10)#7、测试logger.debug('debug')logger.info('info')logger.warning('warning')logger.error('error')logger.critical('critical')

 

5、Logger与Handler的级别

  logger是第一级过滤,然后才能到handler,可以设置level

  

Logger is also the first to filter the message based on a level — if you set the logger to INFO, and all handlers to DEBUG, you still won't receive DEBUG messages on handlers — they'll be rejected by the logger itself. If you set logger to DEBUG, but all handlers to INFO, you won't receive any DEBUG messages either — because while the logger says "ok, process this", the handlers reject it (DEBUG < INFO).#验证import loggingform=logging.Formatter('%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s',                    datefmt='%Y-%m-%d %H:%M:%S %p',)ch=logging.StreamHandler()ch.setFormatter(form)# ch.setLevel(10)ch.setLevel(20)l1=logging.getLogger('root')# l1.setLevel(20)l1.setLevel(10)l1.addHandler(ch)l1.debug('l1 debug')

 

7.应用

  

"""logging配置"""import osimport logging.config# 定义三种日志输出格式 开始standard_format = '[%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d]' \                  '[%(levelname)s][%(message)s]' #其中name为getlogger指定的名字simple_format = '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s'id_simple_format = '[%(levelname)s][%(asctime)s] %(message)s'# 定义日志输出格式 结束logfile_dir = os.path.dirname(os.path.abspath(__file__))  # log文件的目录logfile_name = 'all2.log'  # log文件名# 如果不存在定义的日志目录就创建一个if not os.path.isdir(logfile_dir):    os.mkdir(logfile_dir)# log文件的全路径logfile_path = os.path.join(logfile_dir, logfile_name)# log配置字典LOGGING_DIC = {    'version': 1,    'disable_existing_loggers': False,    'formatters': {        'standard': {            'format': standard_format        },        'simple': {            'format': simple_format        },    },    'filters': {},    'handlers': {        #打印到终端的日志        'console': {            'level': 'DEBUG',            'class': 'logging.StreamHandler',  # 打印到屏幕            'formatter': 'simple'        },        #打印到文件的日志,收集info及以上的日志        'default': {            'level': 'DEBUG',            'class': 'logging.handlers.RotatingFileHandler',  # 保存到文件            'formatter': 'standard',            'filename': logfile_path,  # 日志文件            'maxBytes': 1024*1024*5,  # 日志大小 5M            'backupCount': 5,            'encoding': 'utf-8',  # 日志文件的编码,再也不用担心中文log乱码了        },    },    'loggers': {        #logging.getLogger(__name__)拿到的logger配置        '': {            'handlers': ['default', 'console'],  # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕            'level': 'DEBUG',            'propagate': True,  # 向上(更高level的logger)传递        },    },}def load_my_logging_cfg():    logging.config.dictConfig(LOGGING_DIC)  # 导入上面定义的logging配置    logger = logging.getLogger(__name__)  # 生成一个log实例    logger.info('It works!')  # 记录该文件的运行状态if __name__ == '__main__':    load_my_logging_cfg()
"""MyLogging Test"""import timeimport loggingimport my_logging  # 导入自定义的logging配置logger = logging.getLogger(__name__)  # 生成logger实例def demo():    logger.debug("start range... time:{}".format(time.time()))    logger.info("中文测试开始。。。")    for i in range(10):        logger.debug("i:{}".format(i))        time.sleep(0.2)    else:        logger.debug("over range... time:{}".format(time.time()))    logger.info("中文测试结束。。。")if __name__ == "__main__":    my_logging.load_my_logging_cfg()  # 在你程序文件的入口加载自定义logging配置    demo()

 

#1、有了上述方式我们的好处是:所有与logging模块有关的配置都写到字典中就可以了,更加清晰,方便管理#2、我们需要解决的问题是:    1、从字典加载配置:logging.config.dictConfig(settings.LOGGING_DIC)    2、拿到logger对象来产生日志    logger对象都是配置到字典的loggers 键对应的子字典中的    按照我们对logging模块的理解,要想获取某个东西都是通过名字,也就是key来获取的    于是我们要获取不同的logger对象就是    logger=logging.getLogger('loggers子字典的key名')        但问题是:如果我们想要不同logger名的logger对象都共用一段配置,那么肯定不能在loggers子字典中定义n个key    'loggers': {            'l1': {            'handlers': ['default', 'console'],  #            'level': 'DEBUG',            'propagate': True,  # 向上(更高level的logger)传递        },        'l2: {
'handlers': ['default', 'console' ], 'level': 'DEBUG', 'propagate': False, # 向上(更高level的logger)传递 }, 'l3': { 'handlers': ['default', 'console'], # 'level': 'DEBUG', 'propagate': True, # 向上(更高level的logger)传递 },} #我们的解决方式是,定义一个空的key 'loggers': { '': { 'handlers': ['default', 'console'], 'level': 'DEBUG', 'propagate': True, },}这样我们再取logger对象时logging.getLogger(__name__),不同的文件__name__不同,这保证了打印日志时标识信息不同,但是拿着该名字去loggers里找key名时却发现找不到,于是默认使用key=''的配置

 

re模块

 

http://blog.csdn.net/yufenghyc/article/details/51078107

  

# =================================匹配模式=================================#一对一的匹配# 'hello'.replace(old,new)# 'hello'.find('pattern')#正则匹配import re#\w与\Wprint(re.findall('\w','hello egon 123')) #['h', 'e', 'l', 'l', 'o', 'e', 'g', 'o', 'n', '1', '2', '3']print(re.findall('\W','hello egon 123')) #[' ', ' ']#\s与\Sprint(re.findall('\s','hello  egon  123')) #[' ', ' ', ' ', ' ']print(re.findall('\S','hello  egon  123')) #['h', 'e', 'l', 'l', 'o', 'e', 'g', 'o', 'n', '1', '2', '3']#\n \t都是空,都可以被\s匹配print(re.findall('\s','hello \n egon \t 123')) #[' ', '\n', ' ', ' ', '\t', ' ']#\n与\tprint(re.findall(r'\n','hello egon \n123')) #['\n']print(re.findall(r'\t','hello egon\t123')) #['\n']#\d与\Dprint(re.findall('\d','hello egon 123')) #['1', '2', '3']print(re.findall('\D','hello egon 123')) #['h', 'e', 'l', 'l', 'o', ' ', 'e', 'g', 'o', 'n', ' ']#\A与\Zprint(re.findall('\Ahe','hello egon 123')) #['he'],\A==>^print(re.findall('123\Z','hello egon 123')) #['he'],\Z==>$#^与$print(re.findall('^h','hello egon 123')) #['h']print(re.findall('3$','hello egon 123')) #['3']# 重复匹配:| . | * | ? | .* | .*? | + | {n,m} |#.print(re.findall('a.b','a1b')) #['a1b']print(re.findall('a.b','a1b a*b a b aaab')) #['a1b', 'a*b', 'a b', 'aab']print(re.findall('a.b','a\nb')) #[]print(re.findall('a.b','a\nb',re.S)) #['a\nb']print(re.findall('a.b','a\nb',re.DOTALL)) #['a\nb']同上一条意思一样#*print(re.findall('ab*','bbbbbbb')) #[]print(re.findall('ab*','a')) #['a']print(re.findall('ab*','abbbb')) #['abbbb']#?print(re.findall('ab?','a')) #['a']print(re.findall('ab?','abbb')) #['ab']#匹配所有包含小数在内的数字print(re.findall('\d+\.?\d*',"asdfasdf123as1.13dfa12adsf1asdf3")) #['123', '1.13', '12', '1', '3']#.*默认为贪婪匹配print(re.findall('a.*b','a1b22222222b')) #['a1b22222222b']#.*?为非贪婪匹配:推荐使用print(re.findall('a.*?b','a1b22222222b')) #['a1b']#+print(re.findall('ab+','a')) #[]print(re.findall('ab+','abbb')) #['abbb']#{n,m}print(re.findall('ab{2}','abbb')) #['abb']print(re.findall('ab{2,4}','abbb')) #['abb']print(re.findall('ab{1,}','abbb')) #'ab{1,}' ===> 'ab+'print(re.findall('ab{0,}','abbb')) #'ab{0,}' ===> 'ab*'#[]print(re.findall('a[1*-]b','a1b a*b a-b')) #[]内的都为普通字符了,且如果-没有被转意的话,应该放到[]的开头或结尾print(re.findall('a[^1*-]b','a1b a*b a-b a=b')) #[]内的^代表的意思是取反,所以结果为['a=b']print(re.findall('a[0-9]b','a1b a*b a-b a=b')) #[]内的^代表的意思是取反,所以结果为['a=b']print(re.findall('a[a-z]b','a1b a*b a-b a=b aeb')) #[]内的^代表的意思是取反,所以结果为['a=b']print(re.findall('a[a-zA-Z]b','a1b a*b a-b a=b aeb aEb')) #[]内的^代表的意思是取反,所以结果为['a=b']#\# print(re.findall('a\\c','a\c')) #对于正则来说a\\c确实可以匹配到a\c,但是在python解释器读取a\\c时,会发生转义,然后交给re去执行,所以抛出异常print(re.findall(r'a\\c','a\c')) #r代表告诉解释器使用rawstring,即原生字符串,把我们正则内的所有符号都当普通字符处理,不要转义print(re.findall('a\\\\c','a\c')) #同上面的意思一样,和上面的结果一样都是['a\\c']#():分组print(re.findall('ab+','ababab123')) #['ab', 'ab', 'ab']print(re.findall('(ab)+123','ababab123')) #['ab'],匹配到末尾的ab123中的abprint(re.findall('(?:ab)+123','ababab123')) #findall的结果不是匹配的全部内容,而是组内的内容,?:可以让结果为匹配的全部内容print(re.findall('href="(.*?)"','点击'))#['http://www.baidu.com']print(re.findall('href="(?:.*?)"','点击'))#['href="http://www.baidu.com"']#|print(re.findall('compan(?:y|ies)','Too many companies have gone bankrupt, and the next one is my company'))

 

# ===========================re模块提供的方法介绍===========================import re#1print(re.findall('e','alex make love') )   #['e', 'e', 'e'],返回所有满足匹配条件的结果,放在列表里#2print(re.search('e','alex make love').group()) #e,只到找到第一个匹配然后返回一个包含匹配信息的对象,该对象可以通过调用group()方法得到匹配的字符串,如果字符串没有匹配,则返回None。#3print(re.match('e','alex make love'))    #None,同search,不过在字符串开始处进行匹配,完全可以用search+^代替match#4print(re.split('[ab]','abcd'))     #['', '', 'cd'],先按'a'分割得到''和'bcd',再对''和'bcd'分别按'b'分割#5print('===>',re.sub('a','A','alex make love')) #===> Alex mAke love,不指定n,默认替换所有print('===>',re.sub('a','A','alex make love',1)) #===> Alex make loveprint('===>',re.sub('a','A','alex make love',2)) #===> Alex mAke loveprint('===>',re.sub('^(\w+)(.*?\s)(\w+)(.*?\s)(\w+)(.*?)$',r'\5\2\3\4\1','alex make love')) #===> love make alexprint('===>',re.subn('a','A','alex make love')) #===> ('Alex mAke love', 2),结果带有总共替换的个数#6obj=re.compile('\d{2}')print(obj.search('abc123eeee').group()) #12print(obj.findall('abc123eeee')) #['12'],重用了obj

 

import reprint(re.findall("<(?P
\w+)>\w+
","

hello

")) #['h1']print(re.search("<(?P
\w+)>\w+
","

hello

").group()) #

hello

print(re.search("<(?P
\w+)>\w+
","

hello

").groupdict()) #

hello

print(re.search(r"<(\w+)>\w+
","

hello

").group())print(re.search(r"<(\w+)>\w+
","

hello

").group())

 

import reprint(re.findall(r'-?\d+\.?\d*',"1-12*(60+(-40.35/5)-(-4*3))")) #找出所有数字['1', '-12', '60', '-40.35', '5', '-4', '3']#使用|,先匹配的先生效,|左边是匹配小数,而findall最终结果是查看分组,所有即使匹配成功小数也不会存入结果#而不是小数时,就去匹配(-?\d+),匹配到的自然就是,非小数的数,在此处即整数print(re.findall(r"-?\d+\.\d*|(-?\d+)","1-2*(60+(-40.35/5)-(-4*3))")) #找出所有整数['1', '-2', '60', '', '5', '-4', '3']

 

转载于:https://www.cnblogs.com/mrwang1101/p/8232709.html

你可能感兴趣的文章
打表打表何谓打表?
查看>>
MPEG4与.mp4
查看>>
实验5
查看>>
git 下载 安装
查看>>
录制终端信息并回放
查看>>
JS中window.event事件使用详解
查看>>
ES6深入学习记录(一)class方法相关
查看>>
《BI项目笔记》用Excel2013连接和浏览OLAP多维数据集
查看>>
C语言对mysql数据库的操作
查看>>
SQL Server 数据库备份
查看>>
INNO SETUP 获得命令行参数
查看>>
Charles抓取https请求
查看>>
LAMP环境搭建
查看>>
C语言的变量的内存分配
查看>>
clientcontainerThrift Types
查看>>
链接全局变量再说BSS段的清理
查看>>
hdu 1728 逃离迷宫
查看>>
HTML5与CSS3权威指南之CSS3学习记录
查看>>
docker安装部署
查看>>
AVL树、splay树(伸展树)和红黑树比较
查看>>