• pytho day6 <正则表达式、常用模块、反射>


    本节介绍:

    一:正则表达式:

     正则表达并不是python 独有的。在各个语言里都有该语法的介绍。正则表达是处理字符串的强大的处理工具。拥有自己的独特的

    处理方法。和处理引擎。虽然性能没有python 字符串自己函数和方法。但是由于功能强大。

    如上:正则表达式的大致匹配过程是:一次拿出表达式和文本中的字符进行比较,如果没个字符都能匹配,则匹配成功

    否则匹配失败。

    正则表达式其实是含有文本和特殊字符的字符串,这些文本和特殊字符的模式可以识别各种字符串。

    正则表达式的匹配分两种情况:搜索和匹配。搜索search 是在在字符串任意位置查找到匹配的模式。匹配(match)在字符串开始全部或者一部分找到匹配模式。

    正则表达式支持的元字符和语法:

    .   匹配任意除换行符' '外的字符。在DOTALL模式中也能匹配换行符。

    1 import re
    2 str_a='abcdb'
    3 pp=re.findall('a.c',str_a)
    4 print(pp)
    5 ['abc']

    转义符。使后一个字符改变,变为原先的含义。如果字符创中有字符*可以用*或者[*]进行匹配。

    1 import re
    2 str_a='ab*db'
    3 pp=re.findall('.*.',str_a)
    4 print(pp)
    5 ['b*d']
    1 import re
    2 str_a='ab*db'
    3 pp=re.findall('.[*].',str_a)
    4 print(pp)
    5 ['b*d']

    [...] 字符集(字符类).对应的位置可以是字符集中的任意一个字符。字符集中的字符可以逐个列出来,也可以指定范围如[abc]或者[a-c]。第一个字符如果^表示取反,如[^abc]表示不是abc其他的字符。

          所有特殊字符在[]中都失去原先的特殊含义。在字符集中如果使用]、-或^可以用转义符进行转移。或把]   、-放在第一个字符,^ 放在非第一个字符位置。

    1 import re
    2 str_a='ab*db'
    3 pp=re.findall('[a*b]',str_a)#满足字符集中[]任意一个字符就输出。
    4 print(pp)
    5 ['a', 'b', '*', 'b']
    import re
    str_a='ac*db'
    pp=re.findall('[^ab]',str_a)#表示非ab字符以外的字符
    print(pp)
    ['c', '*', 'd']
    1 import re
    2 str_a='ac.db'
    3 pp=re.findall('[^.ab]',str_a)
    4 print(pp)
    5 ['c', 'd']

    预定义字符集(可以写在字符集[]中)

    d  表示数字[0-9]

    1 import re
    2 str_a='ac.d65b'
    3 pp=re.findall('[ddb]',str_a)
    4 print(pp)
    5 ['d', '6', '5', 'b']
    1 import re
    2 str_a='ac.d6b'
    3 pp=re.findall('ddb',str_a)
    4 print(pp)
    5 ['d6b']

     D 表示非数字[^d]

    import re
    str_a='ac.d6bdab'
    pp=re.findall('dDb',str_a)
    print(pp)
    ['dab']
    1 import re
    2 str_a='ac.d6bdab'
    3 pp=re.findall('[D]',str_a)
    4 ppr1=re.findall('[^d]',str_a)
    5 print(pp)
    6 print(ppr1)
    7 ['a', 'c', '.', 'd', 'b', 'd', 'a', 'b']
    8 ['a', 'c', '.', 'd', 'b', 'd', 'a', 'b']
    import re
    str_a='ac.d6bdab'
    ppr1=re.findall('ddb',str_a)
    print(ppr1)
    ['d6b']

     s 空白字符:[空格 fv]

    1 import re
    2 str_a='ac 
    d6bdab'
    3 ppr1=re.findall('acssd',str_a)
    4 print(ppr1)
    5 ['ac 
    d

     S 表示非空白字符。[^s]

    import re
    str_a='ac 
    d6bdab'
    ppr1=re.findall('[^s]',str_a)
    ppr2=re.findall('[S]',str_a)
    print(ppr1)
    print(ppr2)
    ['a', 'c', 'd', '6', 'b', 'd', 'a', 'b']
    ['a', 'c', 'd', '6', 'b', 'd', 'a', 'b']

    w 表示单词字符 [a-z,A-Z ,0-9]

    1 import re
    2 str_a='ac 
    d6bdab'
    3 ppr1=re.findall('[w]',str_a)
    4 ['a', 'c', 'd', '6', 'b', 'd', 'a', 'b']

    W表示非单词字符[^w]

    1 import re
    2 str_a='ac 
    d6bdab'
    3 ppr1=re.findall('[W]',str_a)
    4 
    5 [' ', '
    ']

    数量词 用在字符或者(...)之后。

    * 表示匹配前一个字符0个或者无限个。

    1 import  re
    2 a='ccaaaccaa'
    3 t=re.findall('a*',a)
    4 print(t)
    5 ['', '', 'aaa', '', '', 'aa', ''] #返回一个列表结果集合如果没匹配直接返回None

     +表示前一个字符出现一次或者多次。

    1 import  re
    2 a='ccaaaccaa'
    3 t=re.findall('a+',a)
    4 print(t)
    5 ['aaa', 'aa'

    ?表示前一个字符出现0次或者1次。

    1 import  re
    2 a='ccaaaccaa'
    3 t=re.findall('a?',a)
    4 print(t)
    5 ['', '', 'a', 'a', 'a', '', '', 'a', 'a', '']

    {n}表示前一个字符出现的次数。也可以指定出现次数限制{n,m}

    1 import  re
    2 a='ccaaaccaa'
    3 t=re.findall('ca{3}',a)
    4 print(t)
    5 ['caaa']
    1 import  re
    2 a='ccaaaccaa'
    3 t=re.findall('ca{2,3}',a)
    4 print(t)
    5 ['caaa', 'caa']

    ^不在字符集[]中表示以什么开头,在字符集中表示非字符集中字符以外的意思。也可以用A 也表示以什么开头。这么写是为了没有caret键盘使用的。

    1 import  re
    2 a='caaaccaa'
    3 t=re.findall('^ca',a)
    4 print(t)
    5 ['ca']
    1 import  re
    2 a='caaaaab'
    3 t=re.findall('[^c,a]',a)
    4 print(t)
    5 ['b']

    $表示以前一个字符结尾。或者以  也表示以什么结尾的。

    1 import  re
    2 a='caaaaab'
    3 t=re.findall('.+b$',a)
    4 print(t)
    5 ['caaaaab']

    re1|re2表示符合re1模式或者符合re2模式的正则的表达式。

    1 import  re
    2 a='caaaaab'
    3 t=re.findall('^c|b$',a)
    4 print(t)
    5 ['c', 'b']

    [^....]表示匹配除字符集中任意字符之外的字符。字符集里可以是范围,也可以是枚举的字符。

    1 import  re
    2 a='caaaaab'
    3 t=re.findall('[^a]',a)
    4 print(t)
    5 ['c', 'b']
    1 import  re
    2 a='caaaaab'
    3 t=re.findall('[^a,b]',a)
    4 print(t)
    5 ['c']
    1 import  re
    2 a='caaaaabd'
    3 t=re.findall('[^a-c]',a)
    4 print(t)
    5 ['d']

    (....)匹配括号里的正则表达式,并形成子组、就是对一个正则表达式的匹配结果进行再次分组匹配。

    1 import  re
    2 a='1+2+(2-(1+3))'
    3 t=re.findall('(([^(,)]+))',a)
    4 print(t)
    5 ['1+3']

    外层表达是匹配带()然后分组里的表达式是:且不包含()的字符串。

     或者B 表示的是单词边界。表示无论在字符串的开头还是符串的中间,都可以进行匹配。

    需要注意是前面需要用r元字符,表示后面的正则表达式是原始字符串进行处理而不进行转义。只有在模式情况下 需要这么做。因为在ASSIC 中 表示退格符(backspace)也就是08 需要加入r表示在处理时候把不进行转义当做原始字符串处理。
    1 import  re
    2 a='abc d the cccc'
    3 t=re.findall(r'abc',a)#需要注意是前面需要用r元字符,表示后面的正则表达式是原始字符串进行处理而不进行转义。只有在模式情况下 需要这么做。还有前后需要单词边界也就是说是空格或者其他隔开
    4 print(t)
    5 ['abc']
    
    1 import  re
    2 a='abc d the cccc'
    3 t=re.findall(r'the',a)
    4 print(t)
    5 ['the']
    1 import  re
    2 a='abc d the cccc'
    3 t=re.findall('BtheB',a)
    4 print(t)
    5 []
    1 import  re
    2 a='abc dthecccc'
    3 t=re.findall('BtheB',a)
    4 print(t)
    5 ['the']
    1 import  re
    2 a='thecccc'
    3 t=re.findall('BtheB',a)
    4 print(t)
    5 []

    需要注意B B之间只能匹配字符串中的字符,而且前后需要的字符不可以是空格,不能匹配开头。

    特殊情况:

    元字符?在+ 、*的后面表示匹配的字符串越短越好。在其他的字符前面也表示越短越好。

    1 import  re
    2 a='caaabd'
    3 t=re.search('a+',a)
    4 print(t)
    5 <_sre.SRE_Match object; span=(1, 4), match='aaa'>
    1 import  re
    2 a='caaabd'
    3 t=re.search('a+?',a)
    4 print(t)
    5 <_sre.SRE_Match object; span=(1, 2), match='a'>

    re模块函数:

    1:findall

    findall,获取非重复的匹配列表;如果有一个组则以列表的形式返回,且每个匹配均是字符串;如果模型中有多个组,则以列表形式返回,且每个匹配均是元组;

    空的匹配也会包含在结果中。findall(pattern,string,flags=0)

    1 import  re
    2 a='acdd4.wee2'
    3 r=re.findall('.w.+',a)
    4 print(r)
    5 ['.wee2']
    1 import  re
    2 a='acdd4.wee2'
    3 r=re.findall('(.)w.+',a)
    4 print(r)
    5 ['.']
    1 import  re
    2 a='acdd4.wee2'
    3 r=re.findall('.(w)(.+)',a)
    4 print(r)
    5 [('w', 'ee2')]
    1 origin = "hello tom bcd abcd lge acd 19"
    2 t = re.findall("a((w*)c)(d)", origin)
    3 print(t)
    4 [('bc', 'b', 'd'), ('c', '', 'd')]

    2:sub函数,是指正则匹配模型中,将匹配成功的字符串替换。

    sub(pattern,repl,string,count=0,flags=0)

    pattern:正则模型

    repl:要替换的字符串或者可执行对象。(替换成什么对象或者字符串!)

    string:要匹配的字符串。

    count:匹配的次数。

    flags:匹配模式。

    与分组无关。

    1 import re
    2 a = 'acderf23f'
    3 r=re.sub('^a.{2}',"000",a,1)
    4 print(r)
    5 000erf23f

    3:split函数

    根据正则表达式的匹配的字符串进行切割。

    split(pattern,string,maxsplit=0,flags=0)

    pattern:正则模型

    string:要匹配的字符串

    maxsplit:指定分割个数0表示全部切割。默认是0。

    flags:匹配模式。

    1 a = 'acderf23f'
    2 r=re.split('de.{2}',a)
    3 print(r)
    4 ['ac', '23f']
    1 import re
    2 a = 'acderf23faaadeccc'
    3 r=re.split('de.{2}',a,1)
    4 print(r)
    5 ['ac', '23faaadeccc']
    import re
    a = 'acderf23faaadeccc'
    r=re.split('(de.{2})',a,0)
    print(r)
    ['ac', 'derf', '23faaa', 'decc', 'c']

    如果想显示切割的部分字符串可以用分组来处理()来保留自己想要的部分的。

    4:match函数:

    从字符串开头进行匹配,如果没有的话返回None 等同于^

    match(pattern,string,flags=0)

    pattern:正则表达式模型。

    string:被匹配的字符串。

    flags:匹配的模式。

    无分组:匹配的字符串自动放在group里,因为没有分组,所以groups里没结果。

    1 import re
    2 a = 'acderf23faaadeccc'
    3 r=re.match('a.{2}',a)
    4 print(r.group())
    5 print(r.groups())
    6 print(r.groupdict()
    7 acd
    8 ()
    9 {}

     有分组:

    1 import re
    2 a = 'acderf23faaadeccc'
    3 r=re.match('a(.{2})',a)
    4 print(r.group())
    5 print(r.groups())
    6 print(r.groupdict())
    7 acd
    8 ('cd',)
    9 {}

    r.group()储存的是分组匹配字符串信息。r.groups()储存的是分组信息。r.groupsdict()储存的是别名信息。

     
    1 import re
    2 a = 'acderf23faaadeccc'
    3 r=re.match('a(?P<key>.{2})',a)###?P<自己命名key值>相当于给这个分组定义一个别名。
    4 print(r.group())
    5 print(r.groups())
    6 print(r.groupdict())
    7 acd
    8 ('cd',)
    9 {'key': 'cd'}

     5:search函数

    对字符串进行搜索,匹配到第一个就结束。无匹配返回值是None

    1 import re
    2 a = 'acderf23faaadecaaccccc'
    3 r=re.search('aa.{2}',a)
    4 print(r.group())
    5 print(r.groups())
    6 print(r.groupdict())
    7 aaad
    8 ()
    9 {}
    1 import re
    2 a = 'acderf23faaadecaaccccc'
    3 r=re.findall('aa.{2}',a)
    4 print(r)
    5 ['aaad', 'aacc']

     有分组:

    1 import re
    2 a = 'acderf23faaadecaaccccc'
    3 r=re.search('a(a.{2})',a)
    4 print(r.group())
    5 print(r.groups())
    6 print(r.groupdict())
    7 aaad
    8 ('aad',)
    9 {}
    1 import re
    2 a = 'acderf23faaadecaaccccc'
    3 r=re.search('a(?P<test>a.{2})',a)
    4 print(r.group())
    5 print(r.groups())
    6 print(r.groupdict())
    7 aaad
    8 ('aad',)
    9 {'test': 'aad'}

    常用的正则表达式的匹配:

    IP:
    ^(25[0-5]|2[0-4]d|[0-1]?d?d)(.(25[0-5]|2[0-4]d|[0-1]?d?d)){3}$
    手机号:
    ^1[3|4|5|8][0-9]d{8}$
    邮箱:
    [a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(.[a-zA-Z0-9_-]+)+

     二:算法

    冒泡算法:

    概念:它重复地走访过要排序的数列,一次比较两个元素大小,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越大的元素会经由交换慢慢“浮”到数列的顶端。

    实现:

    1 NUM_LIST=[5,23,7,2,3,5,7]
    2 LEN=len(NUM_LIST)
    3 for m in range(LEN-1):
    4     for i in range(LEN-1):
    5         if NUM_LIST[i] >NUM_LIST[i+1]:
    6             NUM_LIST[i],NUM_LIST[i+1]=NUM_LIST[i+1],NUM_LIST[i]
    7 print(NUM_LIST)
    8 [2, 3, 5, 5, 7, 7, 23]

    三:模块

    os模块

    1:os.getcwd() 获取当前工作目录,即当前python脚本工作的目录路径

    1 import os
    2 print(os.getcwd())
    3 C:python2day6:

    os.chdir("dirname") 改变当前脚本工作目录;相当于shell下cd
    os.curdir 返回当前目录: ('.')
    os.pardir 获取当前目录的父目录字符串名:('..')
    os.makedirs('dir1/dir2') 可生成多层递归目录
    os.removedirs('dirname1') 若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推
    os.mkdir('dirname') 生成单级目录;相当于shell中mkdir dirname
    os.rmdir('dirname') 删除单级空目录,若目录不为空则无法删除,报错;相当于shell中rmdir dirname
    os.listdir('dirname') 列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印
    os.remove() 删除一个文件
    os.rename("oldname","new") 重命名文件/目录
    os.stat('path/filename') 获取文件/目录信息
    os.sep 操作系统特定的路径分隔符,win下为"\",Linux下为"/"
    os.linesep 当前平台使用的行终止符,win下为" ",Linux下为" "
    os.pathsep 用于分割文件路径的字符串
    os.name 字符串指示当前使用平台。win->'nt'; Linux->'posix'
    os.system("bash command") 运行shell命令,直接显示
    os.environ 获取系统环境变量
    2:os.path.abspath(path) 返回path规范化的绝对路径

    1 import os
    2 print(os.path.abspath(__file__))
    3 C:python2day6s3

    os.path.split(path) 将path分割成目录和文件名二元组返回
    3:os.path.dirname(path) 返回path的目录。其实就是os.path.split(path)的第一个元素

    1 import os
    2 print(os.path.dirname(os.path.abspath(__file__)))
    3 C:python2day6

    4:os.path.basename(path) 返回path最后的文件名。如何path以/或结尾,那么就会返回空值。即os.path.split(path)的第二个元素

    1 import os
    2 print(os.path.basename(__file__))
    3 s3

    5:os.path.exists(path) 如果path存在,返回True;如果path不存在,返回False

    1 import os
    2 print(os.path.exists('C:python2day6\3.py'))
    3 True

    os.path.isabs(path) 如果path是绝对路径,返回True
    os.path.isfile(path) 如果path是一个存在的文件,返回True。否则返回False
    os.path.isdir(path) 如果path是一个存在的目录,则返回True。否则返回False
    6:os.path.join(path1[, path2[, ...]]) 将多个路径组合后返回,第一个绝对路径之前的参数将被忽略

    1 import os
    2 p_dir='C:python2'
    3 c_dir='day6'
    4 print(os.path.join(p_dir,c_dir))
    5 C:python2day6

    os.path.getatime(path) 返回path所指向的文件或者目录的最后存取时间
    os.path.getmtime(path) 返回path所指向的文件或者目录的最后修改时间 

    sys模块:主要用于python解释器相关的。

    1:sys.argv:获取参数,第一个参数是文件路径(相对路径)

    2:sys.exit()程序退出。

    3:sys.version 获取解释版本。

    1 import sys
    2 print(sys.version)
    3 3.5.1 (v3.5.1:37a07cee5969, Dec  6 2015, 01:38:48) [MSC v.1900 32 bit (Intel)] 

    4:sys.path:获取python加载模块的路径。初始化的使用PYTHONPATH的值。

    5:sys.plarform获取操作系统版本。

    1 import sys
    2 print(sys.platform)
    3 win32 

    6:

    sys.stderr 错误输出
    sys.stdin 输入相关
    sys.stdout 输出相关
    练习:进度条模拟:
     1 import sys
     2 import time
     3 
     4 
     5 def view_bar(num, total):
     6     rate = float(num) / float(total)
     7     rate_num = int(rate * 100)
     8     r = '
    %d%%' % (rate_num, )###
    回到行首位置。
     9     sys.stdout.write(r)##输出一行 不带
    
    10     sys.stdout.flush()##将缓存区内容刷到终端,我们写的东西现在缓存区,然后在写在终端。
    11 
    12 
    13 if __name__ == '__main__':
    14     for i in range(0, 101):
    15         time.sleep(0.1)
    16         view_bar(i, 100)

    四:反射:很重要!

    背景:当用户访问网站的时候,输入url的时候,网站后台可以根据用户的输入的字符串,去执行后台程序的相应的方法,相当于web的路由系统。是路由系统的雏形。

    概念:利用字符串形式的去对象中操作(寻找(getattr)、检查(hasattr)、删除(delattr)、设置(setattr))成员。

    注意:

    函数名和字符串是不一样,函数名代指函数体,类似变量,而字符串只是类型为字符串没其他意思。

     

    1 import  web
    2 choice=input('Entre your url:')
    3 if hasattr(web,choice):##判断字符串choice在对象web是否有叫choice的名字的方法和函数中。返回值是布尔值。
    4     fun=getattr(web,choice)##getattr是获取对象web模块的中的choice成员的方法,这里是函数。
    5     fun()##然后调用该函数。
    6 else:
    7     print('sorry you access web is not exits!')
    8 Entre your url:a
    9 sorry you access web is not exits!
    hasattr判断对象中是否该成员。getattr是获取对象的成员,如上,并没有调用该对象。如果需要调用,需要调用执行该成员,上例子是函数,需要执行func()。
    输入的字符串需要和调用的对象成员名字一致,否则调用不成功。
    也就是应用场景需要根据用户的输入,来执行相应的方法。应用场景最多是web开发中。
    setattr和delattr 进行操作的是在内存中,在程序再次加载的时候,之前的操作将会失效。









  • 相关阅读:
    男子头部胀痛案
    摩这些穴位可以对付突发的疾病
    跟师学习时的几个经验方
    黄褐斑良方--- 疏肺散斑汤
    食积咳嗽的特点
    牙痛用药口决(来源于网络暂未验证)
    20多年脚气起泡脱皮瘙痒外洗方治验案
    起死回生通关散
    腰突辩治心得(付济华)
    战痘良方--付济华
  • 原文地址:https://www.cnblogs.com/evilliu/p/5581001.html
Copyright © 2020-2023  润新知