第23天 常用模块四

发布时间:2019-03-19 21:10:53编辑:auto阅读(2010)

    介绍的模块

    re模块
    subprocess模块

    人生三问

    什么re模块
        主要是与正则表达式相关操作的一些方法
    
    什么是正则表达式
        就是一系列特殊意义字符的组成的式子。
    
    为什么要用正则表达式呢?
        在日常生活中我们获得的数据大部分都是一大串的字符串,但是通常情况下我们并不是需要整个字符串,我们需要的是一些有规律的数据,怎么去把他们提取出来就变成了一个难题,
       这个时候正则表达式就出现了,我们可以通过写的一些正则表达式对字符串进行分析提取,最后获得我们需要的内容。

    正则表达式:

    '''
    正则表达式
    位置匹配
        \A 开头
        \Z 结尾
        ^  开头
        $  结尾
    范围匹配
        \d   数字   (\D相反是非数字)
        \w   数字字母下划线  (\W相反)
        \s   空字符(\t\n\f\b) (\s相反)
        [...]   手动指定范围,ascii码表返回
        [^...]  指定范围以外的内容
    重复匹配 
        *   0次或者多次
        +   一次或者多次
        ?   0次或者一次     非贪婪模式
        {n} 精确匹配前面n个表达式
        {n, m} 匹配n到m次由前面的正则表达式定义的片段,贪婪模式
        
    分组    
        ()括号内的表达式是一个分组
    '''

    示例一:单个字符的匹配

    >>> import re
    >>> re.findall('\w', 'hello egon 123')
    ['h', 'e', 'l', 'l', 'o', 'e', 'g', 'o', 'n', '1', '2', '3']
    >>> re.findall('\W', 'hello egon 123')
    [' ', ' ']
    >>> re.findall('\d', 'hello egon 123')
    ['1', '2', '3']
    >>> re.findall('\D', 'hello egon 123')
    ['h', 'e', 'l', 'l', 'o', ' ', 'e', 'g', 'o', 'n', ' ']
    >>> re.findall('\s', 'hello egon 123')
    [' ', ' ']
    >>> re.findall('\S', 'hello egon 123')
    ['h', 'e', 'l', 'l', 'o', 'e', 'g', 'o', 'n', '1', '2', '3']
    >>> re.findall('\Ahe', 'hello egon 123')
    ['he']
    >>> re.findall('^he', 'hello egon 123')
    ['he']
    >>> re.findall('3$', 'hello egon 123')
    ['3']
    >>> re.findall('3\Z', 'hello egon 123')
    ['3']

    示例二:重复匹配

    # 重复匹配之.
    >>> re.findall('a.b', 'a1b')  # 任意字符
    ['a1b']
    >>> re.findall('a.b', 'a1b a*b a b aaab')
    ['a1b', 'a*b', 'a b', 'aab']
    >>> re.findall('a.b', 'a\nb')  # 不能匹配换行符
    []
    >>> re.findall('a.b', 'a\nb', re.S)  # 只要加上这个参数就可以匹配换行符
    ['a\nb']
    >>> re.findall('a.b', 'a\nb', re.DOTALL)
    ['a\nb']
    # 重复匹配之 * 0次或者多次
    >>> re.findall('ab*', 'bbbbbb') # 没有匹配到前面的a
    []
    >>> re.findall('ab*', 'a')  # 匹配了b零次
    ['a']
    >>> re.findall('ab*', 'abbbb')  # 匹配了b多次
    ['abbbb']
    # 重复匹配之? 0次或者一次
    >>> re.findall('ab?', 'a')  # 匹配了b零次
    ['a']
    >>> re.findall('ab?', 'abbbb')  # 匹配了b1次
    ['ab']
    # 重复匹配之 + 1次或者多次
    >>> re.findall('ab+', 'a')  # 没有匹配到b
    []
    >>> re.findall('ab+', 'ab')  # 匹配了b1次
    ['ab']
    >>> re.findall('ab+', 'abbbbb') # 匹配了b多次
    ['abbbbb']

    示例三:{ }, [ ]的使用

    正则表达式之{}
    {2} 匹配前面模式两次
    {2,4}匹配前面模式两到四次,注意中间不能加空格
    >>> re.findall('ab{2}', 'abbb')  # 匹配了b两次
    ['abb']
    >>> re.findall('ab{2,4}','abbb') # 匹配字符2次到四次
    ['abbb']
    >>> re.findall('ab{1,}', 'abbb')  # 匹配1次或者多次,默认贪婪匹配,所以匹配了三次
    ['abbb']
    >>> re.findall('ab{0,}', 'abbb') # 匹配0次或者多次,默认贪婪匹配,所以匹配了三次
    ['abbb']
    >>>
    
    正则表达式之[]
    [abcd] 匹配[]里面的任何字符
    >>> re.findall('a[1*-]b', 'a1b a*b a-b')  # a和b是固定的,但是中间的值可以是1 * -
    ['a1b', 'a*b', 'a-b']
    >>> re.findall('a[^1*-]b', 'a1b a*b a-b a=b') # ^代表a和b之间不能是[]内的任意字符
    ['a=b']
    >>> re.findall('a[0-9]b', 'a1b a*b a-b a=b')   # ab之间可以是0-9之间的数字
    ['a1b']
    >>> re.findall('a[a-z]b', 'a1b a*b a-b asb')   # ab之间是a-z之间的数字
    ['asb']
    >>> re.findall('a[A-Z]b', 'aSb a*b a-b asb')    # ab之间是A-Z之间的数字
    ['aSb']
    >>> re.findall('a[A-Za-z]b', 'aSb a*b a-b asb')  # ab之间是A-Z,a-z之间的数字
    ['aSb', 'asb']
    
    匹配网址
    import re
    
    print(re.findall('href=".*?"', '<a href="http://www.baidu.com">点击</a>'))
    # 结果:['href="http://www.baidu.com"']
    print(re.findall('href="(http.*?)"', '<a href="http://www.baidu.com">点击</a>'))
    # 结果 ['http://www.baidu.com']

    示例四: 分组

    #():分组
    print(re.findall('ab+','ababab123')) #['ab', 'ab', 'ab']
    print(re.findall('(ab)+123','ababab123')) #['ab'],匹配到末尾的ab123中的ab
    print(re.findall('(?:ab)+123','ababab123')) #findall的结果不是匹配的全部内容,而是组内的内容,?:可以让结果为匹配的全部内容

    示例五:【\】的使用

    # 因为python在使用正则表达式的时候是要交给底层的c去执行的
    # 因此python解释器首先要保证让自己去识别斜杠的时候是正确的,这个时候需要两个斜杠
    # 当时当传到底层的c去执行的时候,需要把让c也知道这个是普通的字符,因此还需要两个斜杠
    text = 'a\c'
    # 方法一:四个斜杠
    print(re.findall('a\\\\c', text))
    # 方法二: r + 两个斜杠
    print(re.findall(r'a\\c', text))
    # 结果:
    # ['a\\c']
    # ['a\\c']

    re模块的方法

    re模块的方法
        findall  返回所有满足匹配条件的值放在一个列表中
        search   在整个字符串中寻找一个匹配的值
        match  从字符串的开头寻找一个匹配的值
        split  按照一个模式进行分割
        sub   替换字符串
       complie  编译

    方法一: 匹配

    >>> import re
    >>> re.findall('e', 'alex make love') # 在字符串中查找出所有的e放在一个列表中
    ['e', 'e', 'e']
    >>> re.search('e', 'alex make love') # 在字符串中查找出一个e返回一个对象,可以通过group去获得相应的值
    <_sre.SRE_Match object; span=(2, 3), match='e'>
    >>> re.search('e', 'alex make love').group(0)
    'e'
    >>> re.match('e', 'alex make love') # 在字符串的开头查找e发现没有,所以没有返回值,方法match可以被search + ^方法所取代
    >>>

    方法二:compile

    >>> obj = re.compile('\d{2}')  # 直接把字符串编译成对象之后可以通过方法去直接调用
    >>> obj.search('abc123eeee').group()  # 对象直接调用search去查找对应的值
    '12'
    >>> obj.findall('abc123eeee')  #对之前编译的对象进行了重用
    ['12']
    >>>

    方法三: sub

    # 替换字符串,第一个给匹配模块,第二个为替换对象,第三个为字符串,第四个是替换几个
    >>> re.sub('a', 'A', 'alex make love') 'Alex mAke love' >>> re.sub('a', 'A', 'alex make love', 1) 'Alex make love' >>> re.sub('a', 'A', 'alex make love', 2) 'Alex mAke love' >>>

    应用一:将字符串的alex make love的第一个字符串和第三个字符串进行替换====》love make alex

    # alex make love ===>love make alex
    text = 'alex make love'
    # 首先用正则表达式去表示我们的字符串,表示成五组,[('alex', ' ', 'make', ' ', 'love', '')]
    pattern = '^(\w+)(.*?\s)(\w+)(.*?\s)(\w+)(.*?)$'
    # print(re.findall(pattern, text))
    print(re.sub(pattern, r'\5\2\3\4\1', text))

    应用二:将字符"java|C++|js|C|python"替换成python|C++|js|C|java

    # 将字符串java与python进行替换
    text = "java|C++|js|C|python"   # 这是一段字符串
    pattern = '(.+?)(\|.+\|)(.+)'  # 首先通过正则表达式去描述我们的字符串,并且分组
    # print(re.findall(pattern, text))
    print(re.sub(pattern, r'\3\2\1', text))  # 根据分组去获得我们的值

    方法四:split

    print(re.split("\|_*\|","python|____|js|____|java"))

    模块二:subprocess

    subprocess
        这是一个可以与其他进程进行数据交互的模块。
    os.system
      也可以和其他的进程进行交换,但是不能进行数据交互,我们只能得到一个状态码。
    两个输出,一个输入
      stdout 标准输出
      stdin  标准输入
      stderr 标准错误输出

    方法:Popen

    标准输出

    import subprocess
    
    cmd = 'dir H:\python_study\day23 | findstr "py"'
    # 创建了一个子进程, 把命令,标准输出
    sub = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
    # 得到的是系统的编码方式,是gbk的编码方式
    print(sub.stdout.read().decode('gbk'))

    标准错误输出

    import subprocess
    
    cmd = 'd H:\python_study\day23 | findstr "py"'
    # 创建了一个子进程, 把命令,标准输出
    sub = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True, stderr=subprocess.PIPE)
    # 得到的是系统的编码方式,是gbk的编码方式
    # print(sub.stdout.read().decode('gbk'))
    # 这个是当错误发生的时候会给我们返回一个标准错误输出
    print(sub.stderr.read().decode('gbk'))

    标准输入:

    cmd = 'dir H:\python_study\day23'
    find = 'findstr "py"'
    
    sub1 = subprocess.Popen(cmd,
                            stdout=subprocess.PIPE,
                            shell=True,)
    # 把sub1的标准输出输入到sub2的输入中
    sub2 = subprocess.Popen(find,
                            stdout=subprocess.PIPE,
                            stdin=sub1.stdout)
    
    print(sub2.stdout.read().decode('gbk'))

     

关键字