zoukankan      html  css  js  c++  java
  • python常用模块(二)


     1.ConfigParser模块

    用于生成和修改配置文档,在python3.x中变更为configparser

     1 [DEFAULT]
     2 ServerAliveInterval = 45
     3 Compression = yes
     4 CompressionLevel = 9
     5 ForwardX11 = yes
     6  
     7 [bitbucket.org]
     8 User = hg
     9  
    10 [topsecret.server.com]
    11 Port = 50022
    12 ForwardX11 = no
    常见conf格式
     1 import configparser
     2  
     3 config = configparser.ConfigParser()
     4 config["DEFAULT"] = {'ServerAliveInterval': '45',
     5                       'Compression': 'yes',
     6                      'CompressionLevel': '9'}
     7  
     8 config['bitbucket.org'] = {}
     9 config['bitbucket.org']['User'] = 'hg'
    10 config['topsecret.server.com'] = {}
    11 topsecret = config['topsecret.server.com']
    12 topsecret['Host Port'] = '50022'     # mutates the parser
    13 topsecret['ForwardX11'] = 'no'  # same here
    14 config['DEFAULT']['ForwardX11'] = 'yes'
    15 with open('example.ini', 'w') as configfile:
    16    config.write(configfile)
    17 
    18 #读取
    19 >>> import configparser
    20 >>> config = configparser.ConfigParser()
    21 >>> config.sections()
    22 []
    23 >>> config.read('example.ini')
    24 ['example.ini']
    25 >>> config.sections()
    26 ['bitbucket.org', 'topsecret.server.com']
    27 >>> 'bitbucket.org' in config
    28 True
    29 >>> 'bytebong.com' in config
    30 False
    31 >>> config['bitbucket.org']['User']
    32 'hg'
    33 >>> config['DEFAULT']['Compression']
    34 'yes'
    35 >>> topsecret = config['topsecret.server.com']
    36 >>> topsecret['ForwardX11']
    37 'no'
    38 >>> topsecret['Port']
    39 '50022'
    40 >>> for key in config['bitbucket.org']: print(key)
    41 ...
    42 user
    43 compressionlevel
    44 serveraliveinterval
    45 compression
    46 forwardx11
    47 >>> config['bitbucket.org']['ForwardX11']
    48 'yes'
    49 
    50 #增删改查
    51 [section1]
    52 k1 = v1
    53 k2:v2
    54   
    55 [section2]
    56 k1 = v1
    57  
    58 import ConfigParser
    59   
    60 config = ConfigParser.ConfigParser()
    61 config.read('i.cfg')
    62   
    63 # ########## 读 ##########
    64 #secs = config.sections()
    65 #print secs
    66 #options = config.options('group2')
    67 #print options
    68   
    69 #item_list = config.items('group2')
    70 #print item_list
    71   
    72 #val = config.get('group1','key')
    73 #val = config.getint('group1','key')
    74   
    75 # ########## 改写 ##########
    76 #sec = config.remove_section('group1')
    77 #config.write(open('i.cfg', "w"))
    78   
    79 #sec = config.has_section('wupeiqi')
    80 #sec = config.add_section('wupeiqi')
    81 #config.write(open('i.cfg', "w"))
    82   
    83   
    84 #config.set('group2','k1',11111)
    85 #config.write(open('i.cfg', "w"))
    86   
    87 #config.remove_option('group2','age')
    88 #config.write(open('i.cfg', "w"))
    使用模块生成

    2.hashlib模块

    用于加密相关的操作,3.x里代替了md5模块和sha模块,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法

     1 import hashlib
     2 
     3 -----md5-----
     4 md_five = hashlib.md5()
     5 md_five.update(b'Hello World')            #加密
     6 
     7 print(md_five.digest())                         #二进制hash
     8 print(md_five.hexdigest())                   #十六进制hash
     9 
    10 '''
    11 def digest(self, *args, **kwargs): # real signature unknown
    12     """ Return the digest value as a string of binary data. """
    13     pass
    14  
    15 def hexdigest(self, *args, **kwargs): # real signature unknown
    16     """ Return the digest value as a string of hexadecimal digits. """
    17     pass
    18  
    19 '''
    20 ----sha1-----
    21 md_five = hashlib.sha1()
    22 md_five.update(b'Hello World')
    23 
    24 print(md_five.hexdigest())
    25 
    26 -----sha256-----
    27 md_five = hashlib.sha256()
    28 md_five.update(b'Hello World')
    29 
    30 print(md_five.hexdigest())
    31 
    32 -----sha384-----
    33 md_five = hashlib.sha384()
    34 md_five.update(b'Hello World')
    35 
    36 print(md_five.hexdigest())
    37 
    38 -----sha512-----
    39 md_five = hashlib.sha512()
    40 md_five.update(b'Hello World')
    41 
    42 print(md_five.hexdigest())
    43 
    44 
    45 #还有一个,这个就是相当于双层加密,大家应该都知道撞库啊,那么用了这个你解掉一层还有一层,是不是非常的牛X!
    46 
    47 #HMAC:散列消息鉴别码,简称HMAC,是一种基于消息鉴别码MAC(Message Authentication Code)的鉴别机制。使用HMAC时,消息通讯的双方,通过验证消息中加入的鉴别密钥K来鉴别消息的真伪;
    48 一般用于网络通信中消息加密,前提是双方先要约定好key,就像接头暗号一样,然后消息发送把用key把消息加密,接收方用key + 消息明文再加密,拿加密后的值 跟 发送者的相对比是否相等,这样就能验证消息的真实性,及发送者的合法性了。
    49 
    50 #怎么用呢???
    51 import hmac
    52 
    53 hm = hmac.new(b'Hello World!','你好世界!'.encode(encoding="utf-8"))
    54 print(hm.digest())
    55 print(hm.hexdigest())
    View Code

    3.subprocess模块

      这个模块跟os模块有点类似,也是可以和操作系统进行交互

      我们这里举个例子

      

    import os
    
    os.system("dir")
    #这里会直接打印到屏幕上,也就是直接输出结果,那我想储存到一个变量里可以吗?
    a = os.system("dir")
    a
    >>>0
    #为什么输出的是0呢?os.system()只能输出命令结果到屏幕,赋值则返回的是命令执行结果,0为成功,失败则为非0而不是1
    
    #那么我想保存到一个变量里就要用os.popen()
    os.popen("dir"),read

      subprocess是从3.x的新模块,比os更好用,接下来我们就举一些例子

    import subprocess
    
    #run
    subprocess.run("df -h",shell = True)
    #命令正常则执行0,命令错误会报错
    
    #call
    subprocess.call("df -h",shell = True)
    #命令正常则执行并返回状态0,命令错误会报错并返回状态非0
    
    #check_call
    subprocess.echk_call("df -h",shell = True)
    #同上
    
    #getstatusoutput
    subprocess.getstatusoutput('mkdir -p /Q/Q/Q')
    >>>(0, '')
    #接收命令,以元组的方式返回,第一个为执行状态,第二个为执行结果
    
    #getoutput
    #跟上面比没有执行状态
    
    #check_output
    subprocess.check_output("ls -l",shell = True)
    #直接返回结果,以二进制方式返回
    
    #上面的这些底层封装的都是subprocess.Popen
    例子:
    a = subprocess.Popen("pwd",shell = True,stdout = subprocess.PIPE)
    a.stdout.read()
    
    #stdin:标准输入
    #stdout:标准输出
    #stderr:标准错误
    
    #poll
    a = subprocess.Popen("sleep 10;echo 'hehe'",shell = True,stdout=subprocess.PIPE)
    print(a.poll())
    >>>None
    print(a.poll())
    >>>0
    #查询执行状态,未执行完返回None,执行完返回0,执行失败返回非0,有一个类似的是wait()
    
    #terminate:杀掉所启动进程
    #communicate:等待任务结束

    可用参数:

      • args:shell命令,可以是字符串或者序列类型(如:list,元组)
      • bufsize:指定缓冲。0 无缓冲,1 行缓冲,其他 缓冲区大小,负值 系统缓冲
      • stdin, stdout, stderr:分别表示程序的标准输入、输出、错误句柄
      • preexec_fn:只在Unix平台下有效,用于指定一个可执行对象(callable object),它将在子进程运行之前被调用
      • close_sfs:在windows平台下,如果close_fds被设置为True,则新创建的子进程将不会继承父进程的输入、输出、错误管道。
        所以不能将close_fds设置为True同时重定向子进程的标准输入、输出与错误(stdin, stdout, stderr)。
      • shell:同上
      • cwd:用于设置子进程的当前目录
      • env:用于指定子进程的环境变量。如果env = None,子进程的环境变量将从父进程中继承。
      • universal_newlines:不同系统的换行符不同,True -> 同意使用
      • startupinfo与createionflags只在windows下有效
        将被传递给底层的CreateProcess()函数,用于设置子进程的一些属性,如:主窗口的外观,进程的优先级等等

    终端输入的命令分为两种:

      • 输入即可得到输出,如:ifconfig
      • 输入进行某环境,依赖再输入,如:python

     

    4.logging模块

    #做运维的肯定要记录日志,不管是服务的报警还是记录日常的错误以及一些其他信息,日志都是不可或缺的.在python中有一个logging模块使专门用来干这个的,可以用logging模块来记录各种格式的日志,熟悉日志程序的都知道,日志有五个级别,分别是debug()info()warning()error() and critical(),让我们看看5个级别都如何使用

     1 import logging
     2 
     3 logging.warning("Hello World!")
     4 logging.debug("Hello World!")
     5 logging.info("Hello World!")
     6 logging.error("Hello World!")
     7 logging.critical("Hello World!")
     8 >>>WARNING:root:Hello World!
     9 ERROR:root:Hello World!
    10 CRITICAL:root:Hello World!
    11 
    12 #诶,这里为什么只打印除了"warning","error","critical"这三个级别呢?
    13 
    14 #日志肯定是可以写到文件里的,so
    15 logging.basicConfig(filename="cacti.log",level=logging.DEBUG)  #level是日志级别
    16 #这样就写到文件里了,再写就是追加不会覆盖,设置日志级别,只会把比设置的日志级别高的日志写到日志中,比如设置的是error,那么debug就不会出现在日志中
    17 
    18 #那么做运维的就会说了“你TM的时间呢,没有时间我排个毛线的错”,说得好,所以呢:
    19 
    20 logging.basicConfig(filename="cacti.log",level=logging.ERROR,format='%(asctime)s %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p')
    21 logging.error("Hello error")
    22 >>>11/23/2017 02:45:46 PM Hello error
    View Code

     

    #以下是其他格式

    日志格式

    %(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模块记录日志主要分为四个类,请看下面

    1.logger:用户可直接调用

      每个程序在输出信息之前都要获得一个Logger。Logger通常对应了程序的模块名,比如聊天工具的图形界面模块可以这样获得它的Logger:
      LOG=logging.getLogger(”chat.gui”)
      而核心模块可以这样:
      LOG=logging.getLogger(”chat.kernel”)

      Logger.setLevel(lel):指定最低的日志级别,低于lel的级别将被忽略。debug是最低的内置级别,critical为最高
      Logger.addFilter(filt)、Logger.removeFilter(filt):添加或删除指定的filter
      Logger.addHandler(hdlr)、Logger.removeHandler(hdlr):增加或删除指定的handler
      Logger.debug()、Logger.info()、Logger.warning()、Logger.error()、Logger.critical():可以设置的日志级别

    2.handler:将(logger)创建的日志信息发送到指定的输出位置

    handler对象负责发送相关的信息到指定目的地。Python的日志系统有多种Handler可以使用。有些Handler可以把信息输出到控制台,有些Logger可以把信息输出到文件,还有些 Handler可以把信息发送到网络上。如果觉得不够用,还可以编写自己的Handler。可以通过addHandler()方法添加多个多handler
    Handler.setLevel(lel):指定被处理的信息级别,低于lel级别的信息将被忽略
    Handler.setFormatter():给这个handler选择一个格式
    Handler.addFilter(filt)、Handler.removeFilter(filt):新增或删除一个filter对象


    每个Logger可以附加多个Handler。接下来我们就来介绍一些常用的Handler:
    1) logging.StreamHandler
    使用这个Handler可以向类似与sys.stdout或者sys.stderr的任何文件对象(file object)输出信息。它的构造函数是:
    StreamHandler([strm])
    其中strm参数是一个文件对象。默认是sys.stderr


    2) logging.FileHandler
    和StreamHandler类似,用于向一个文件输出日志信息。不过FileHandler会帮你打开这个文件。它的构造函数是:
    FileHandler(filename[,mode])
    filename是文件名,必须指定一个文件名。
    mode是文件的打开方式。参见Python内置函数open()的用法。默认是’a',即添加到文件末尾。

    3) logging.handlers.RotatingFileHandler
    这个Handler类似于上面的FileHandler,但是它可以管理文件大小。当文件达到一定大小之后,它会自动将当前日志文件改名,然后创建 一个新的同名日志文件继续输出。比如日志文件是chat.log。当chat.log达到指定的大小之后,RotatingFileHandler自动把 文件改名为chat.log.1。不过,如果chat.log.1已经存在,会先把chat.log.1重命名为chat.log.2。。。最后重新创建 chat.log,继续输出日志信息。它的构造函数是:
    RotatingFileHandler( filename[, mode[, maxBytes[, backupCount]]])
    其中filename和mode两个参数和FileHandler一样。
    maxBytes用于指定日志文件的最大文件大小。如果maxBytes为0,意味着日志文件可以无限大,这时上面描述的重命名过程就不会发生。
    backupCount用于指定保留的备份文件的个数。比如,如果指定为2,当上面描述的重命名过程发生时,原有的chat.log.2并不会被更名,而是被删除。


    4) logging.handlers.TimedRotatingFileHandler
    这个Handler和RotatingFileHandler类似,不过,它没有通过判断文件大小来决定何时重新创建日志文件,而是间隔一定时间就 自动创建新的日志文件。重命名的过程与RotatingFileHandler类似,不过新的文件不是附加数字,而是当前时间。它的构造函数是:
    TimedRotatingFileHandler( filename [,when [,interval [,backupCount]]])
    其中filename参数和backupCount参数和RotatingFileHandler具有相同的意义。
    interval是时间间隔。
    when参数是一个字符串。表示时间间隔的单位,不区分大小写。它有以下取值:
    S 秒
    M 分
    H 小时
    D 天
    W 每星期(interval==0时代表星期一)
    midnight 每天凌晨

    3.filter:可以用来过滤日志信息(一般用不到)

    4.formatter:就跟上面提到的fomat一样,用于决定输出格式

    #这俩不难,就那么几个用法,就不多说了,接下来我们填一下坑,刚才说到如何同时屏幕输出和文件输出

     1 import logging
     2 logger = logging.getLogger("log")                      #定义一个logger
     3 logger.setLevel(logging.DEBUG)                         #定义logger日志最小级别
     4 
     5 delog = logging.StreamHandler()                       #定义屏幕输出handler
     6 delog.setLevel(logging.DEBUG)
     7 
     8 errlog = logging.FileHandler("error.txt")           #定义文件输出
     9 errlog.setLevel(logging.ERROR)
    10 
    11 delog_format = logging.Formatter("%(asctime)s %(lineno)d %(message)s")   #定义屏幕输出格式
    12 errlog_format = logging.Formatter("%(asctime)s %(message)s")               #定义文件输出格式
    13 delog.setFormatter(delog_format)                                              #给delog增加格式
    14 errlog.setFormatter(errlog_format)                                            #给errlog增加格式
    15 
    16 logger.addHandler(delog)
    17 logger.addHandler(errlog)                                                     #给logger增加handler
    18 
    19 logger.warning("Hello World")
    20 
    21 >>>2017-11-10 22:12:10,480 19 Hello World
    22 
    23 #到这里大家会发现,只有屏幕输出了,为什么文件没有输出呢,因为我们定义的屏幕输出handler的最小级别为error,输出的级别是warning,所以没有输出,利用这个呢我们就可以将一些重大错误输出到文件且报警,而一些类似debug,warning的呢就可以输出到屏幕
    View Code

    #运维平常要看很多日志,可是如果把每一条记录进去,就会造成一个超大的文件,所以会定期删除日志,那么python有一个日志文件截断的功能

     1 import logging
     2 from logging import handlers
     3 logger = logging.getLogger("log")                      #定义一个logger
     4 logger.setLevel(logging.DEBUG)                         #定义logger日志最小级别
     5 
     6 errlog = handlers.RotatingFileHandler(filename="error.log",maxBytes=10,backupCount=3)           
     7 #定义文件输出,到达10个字节则自动将error.log改名为error.log.1,有了.1则变成.2然后在重新创建一个error.log,但是呢最多备份3个
     8 errlog.setLevel(logging.ERROR)
     9 
    10 errlog_format = logging.Formatter("%(asctime)s %(message)s")               #定义文件输出格式
    11 errlog.setFormatter(errlog_format)                                            #给errlog增加格式
    12 
    13 logger.addHandler(errlog)                                                     #给logger增加handler
    14 
    15 logger.error("Hello World")
    16 logger.error("Hello World")
    17 logger.error("Hello World"
    18 #这样你就会发现你多了几个文件*.log.1,*.log.2,*.log.3
    19 
    20 #上面呢是按文件大小来截断,还有一个按时间来截断
    21 
    22 import logging,time
    23 from logging import handlers
    24 logger = logging.getLogger("log")                      #定义一个logger
    25 logger.setLevel(logging.DEBUG)                         #定义logger日志最小级别
    26 
    27 errlog = handlers.TimedRotatingFileHandler(filename="error.log",when="S",interval=1,backupCount=3,encoding="utf-8")          #定义文件输出,文件名,时间单位为秒,1秒备份一次,最多三次
    28 errlog.setLevel(logging.ERROR)
    29 
    30 errlog_format = logging.Formatter("%(asctime)s %(message)s")               #定义文件输出格式
    31 errlog.setFormatter(errlog_format)                                            #给errlog增加格式
    32 
    33 logger.addHandler(errlog)                                                     #给logger增加handler
    34 
    35 logger.error("你好世界1")
    36 time.sleep(2)
    37 logger.error("你好世界2")
    38 time.sleep(2)
    39 logger.error("你好世界3")
    40 time.sleep(2)
    41 logger.error("你好世界4")
    42 time.sleep(2)
    43 logger.error("你好世界5")
    44 #多了三个带时间格式的error.log.2017...
    View Code

     5.re正则表达式模块

    熟悉linux的知道很多用来匹配的语句,比如grep,awk,sed等,那么python中也有一个re也可以做到

    举一些常用的匹配字符:

     1 "."  # 默认匹配除
    之外的任意一个字符,若指定flag DOTALL,则匹配任意字符,包括换行
     2 re.search(".{10}","name:Daniel age:18")
     3 >>><_sre.SRE_Match object; span=(0, 10), match='name:Danie'>
     4 
     5 "^"  #匹配字符开头,若指定flags MULTILINE,这种也可以匹配上
     6 (r"^a","
    abc
    eee",flags=re.MULTILINE)
     7 re.search("^name","name:Daniel age:18")
     8 >>><_sre.SRE_Match object; span=(0, 4), match='name'>
     9 
    10 "$"  # 匹配字符结尾,或re.search("foo$","bfoo
    sdfsf",flags=re.MULTILINE).group()也可以
    11 re.search("18$","name:Daniel age:18")
    12 >>><_sre.SRE_Match object; span=(16, 18), match='18'>
    13 
    14 "*"  #匹配*号前的字符0次或多次,re.findall("ab*","cabb3abcbbac")  结果为['abb', 'ab', 'a']
    15 >>>re.findall("ab*","abbb2abb2ab2")
    16 ['abbb', 'abb', 'ab']
    17 
    18 "+"    #匹配前一个字符1次或多次
    19 >>>re.findall("a+","abbb2abb2ab2")
    20 ['a', 'a', 'a']
    21 
    22 "?"  #匹配前一个字符1次或0次
    23 >>>re.findall("a?","abbb2abb2ab2")
    24 ['a', '', '', '', '', 'a', '', '', '', 'a', '', '', '']
    25 
    26 "{n}"  #匹配前一个字符n次
    27 re.findall("ab{3}","abbb2abb2ab2")
    28 ['abbb']
    29 
    30 "{n,m}"   #匹配前一个字符n到m次
    31 re.findall("ab{1,3}","abbb2abb2ab2")
    32 ['abbb', 'abb', 'ab']
    33 
    34 "|"    #匹配|左或|右的字符
    35 re.findall("AB|ab","ABabbb2abb2ab2")
    36 ['AB', 'ab', 'ab', 'ab']
    37 
    38 '(```)'  #分组匹配
    39  re.findall("(d+)(a|b)","ABabbb2abb2ab2")
    40 >>>[('2', 'a'), ('2', 'a')]
    41 re.search("(?P<name>[A-z]{1,6})(?P<age>[0-9]{2})","Daniel18").groupdict()
    42 >>>{'name': 'Daniel', 'age': '18'}
    43 
    44 
    45 "A" #从头开始匹配
    46 re.findall("AAB","ABabbb2abb2ab2")
    47 >>>['AB']
    48 
    49 ''    #匹配字符结尾,同$
    50 re.findall("2","ABabbb2abb2ab2")
    51 >>>['2']
    52 
    53 "d"   #匹配数字
    54 re.findall("d","ABabbb2abb2ab2")
    55 ['2', '2', '2']
    56 
    57 "D"  #匹配非数字
    58 re.findall("D","ABabbb2abb2ab2")
    59 >>>['A', 'B', 'a', 'b', 'b', 'b', 'a', 'b', 'b', 'a', 'b']
    60 
    61 "w"   #匹配[A-Za-z0-9]
    62 re.findall("w","ABabbb2abb2ab2")
    63 >>>['A', 'B', 'a', 'b', 'b', 'b', '2', 'a', 'b', 'b', '2', 'a', 'b', '2']
    64 
    65 "W"   #匹配非[A-Za-z0-9]
    66 re.findall("W","ABabbb2abb2ab2$!##@")
    67 >>>['$', '!', '#', '#', '@']
    68 
    69 's'     匹配空白字符、	、
    、
     ,
    70 re.search("s+","1
    2	3
    4
    56").group()
    71 >>>'
    '
    View Code

    大家从上面可以看到re.findall,re.search,这些是什么意思呢?还有没有别的呢?

     1 re.match 从头开始匹配
     2 re.match("a+","sa")                           #这里就匹配不到
     3 re.match("a+","asa")
     4 >>><_sre.SRE_Match object; span=(0, 1), match='a'>  #只匹配开头有的
     5 
     6 re.search 匹配包含
     7 re.search("a+","sa")
     8 >>><_sre.SRE_Match object; span=(1, 2), match='a'>      #匹配所有的,一般我们都用这个
     9 
    10 re.findall 把所有匹配到的字符放到以列表中的元素返回
    11 re.findall("a+","asaa")
    12 >>>['a', 'aa']                          #返回所匹配到的元素
    13 
    14 re.split 以匹配到的字符当做列表分隔符
    15  re.split("d+","a1b2c3d4e5")
    16 ['a', 'b', 'c', 'd', 'e', '']                 #把数字都给分割
    17 
    18 re.sub      匹配字符并替换
    19 re.sub("d","~","a1b2c3d4e5f6")
    20 'a~b~c~d~e~f~'                  #将数字替换成~

    反斜杠的困扰
    与大多数编程语言相同,正则表达式里使用""作为转义字符,这就可能造成反斜杠困扰。假如你需要匹配文本中的字符"",那么使用编程语言表示的正则表达式里将需要4个反斜杠"\\":前两个和后两个分别用于在编程语言里转义成反斜杠,转换成两个反斜杠后再在正则表达式里转义成一个反斜杠。Python里的原生字符串很好地解决了这个问题,这个例子中的正则表达式可以使用r"\"表示。同样,匹配一个数字的"\d"可以写成r"d"。有了原生字符串,你再也不用担心是不是漏写了反斜杠,写出来的表达式也更直观。

    re.split("\\",r"usrlocalpython")
    >>>['usr', 'local', 'python']  
    
    re.split("\\",r"usr\localpython")        
    >>>['usr', '', 'local', 'python']
    
    re.split("\/",r"usr\localpython")
    >>>['usr\\local\python']
    
    re.split("/",r"/usr\localpython")
    >>>['', 'usr\\local\python']
    
    
    #四个匹配一个

    到这里你会问了还有吗,还有一点点你需要稍微知道的,当然忘掉也无所谓

     1 re.I(re.IGNORECASE): 忽略大小写
     2 re.findall("a+","abAbAbab",flags=re.I)
     3 >>>['a', 'A', 'A', 'a']
     4 
     5 M(MULTILINE): 多行模式,改变'^''$'的行为
     6 re.findall("^a","abc
    abc
    abc",flags=re.M)
     7 >>>['a', 'a', 'a']               #匹配多行
     8 
     9 re.findall("c$","abc
    abc
    abc",flags=re.M)
    10 >>>['c', 'c', 'c']
    11 
    12 S(DOTALL):改变"."的行为
    13 re.findall(".","abc
    abc
    abc")
    14 >>> ['a', 'b', 'c', 'a', 'b', 'c', 'a', 'b', 'c'] #"."原本是匹配不到'
    '
    15 
    16 re.findall(".","abc
    abc
    abc",flags=re.S)
    17 >>> ['a', 'b', 'c', '
    ', 'a', 'b', 'c', '
    ', 'a', 'b', 'c']  #现在就匹配到

  • 相关阅读:
    《JavaScript高级程序设计》读书笔记(十):本地对象Date
    JavaScript计算字符串中每个字符出现的次数
    JavaScript单元测试ABC
    ASP.NET MVC3 AJAX 上传图片示例
    canvas标签的width和height以及style.width和style.height的区别
    分享一个自定义的 console 类,让你不再纠结JS中的调试代码的兼容
    《JavaScript高级程序设计》阅读笔记(十四):继承机制的实现
    从此不再惧怕URI编码:JavaScript及C# URI编码详解
    Levenshtein算法的JavaScript实现
    《JavaScript高级程序设计》阅读笔记(十五):浏览器中的JavaScript
  • 原文地址:https://www.cnblogs.com/wazy/p/7883320.html
Copyright © 2011-2022 走看看