python关于re库的整理

1,爬取解析一个简单的网页数据都有什么步骤呢?

  1.1,首先应该用requests构建一个请求,将请求成功返回的数据,传递给一个response对象,我们这里先假设这个response对象名字为 r 吧;

  1.2,然后嘛调用BeautifulSoup库,比如BeautifulSoup(r.text,'html.parser')使用html解析器把html页面的源代码解析成易于理解标签形式;

  1.3,正则表达式可以快速分析大量文本找到特定的字符串模式,然后进行提取编辑替换等操作;所以接下来就是对正则表达式的学习了;

 

2,正则表达式  regular expression;属于python标准库;

  2.0,正则表达式定义:正则表达式对应具有特定性质的一组字符串;

             正则表达式形式由普通字符和操作符组成,便于理解就称为正则表达式;经过编译后机器才会认可正则表达式代表一组字符串;

  2.1,正则表达式的常用操作符:

    2.1.1, .   表示除换行符外的任意单个字符;

    2.1.2, [ ] 表示单字符范围;  eg:[abc]表示a或b或c;[a-z]表示a到z中的某一个字符;

    2.1.3, [^  ]  表示单字符排除范围;  eg:[^abc]表示abc之外的任意字符;

         在[ ]里,一些特殊字符[ ]里开头会有特殊意义,还有转义字符会有特殊意义;剩下的特殊字符只是匹配范围;(不确定,我这么理解)

    2.1.4,* 前一个字符任意次扩展,相当于{0,};  eg:abc*表示ab,abc,abcc等;

    2.1.5,+ 前一个字符至少一次扩展,相当于{1,};  eg: abc+表示abc,abcc,abccc等;

    2.1.6,?前一个字符扩展0次或1次,相当于{0,1};  eg: abc?表示ab或abc;

    2.1.7,{m} 前一个字符的m次扩展;  eg:abc{2}表示abcc;

    2.1.8,{m,n}前一个字符的[m,n]次扩展;  eg:ab[1,2]c 表示abc和abbc;

 

    2.1.9,| 表示左右表达式中的任意一个,用在()内,相当于或;  eg: (abc | abd) 表示abc或abd;

    2.1.10,^ 字符串开头匹配;  eg: ^a匹配abc中的a,不匹配abc中的b和c;^b不匹配abc中的b;

    2.1.11,$字符串结尾匹配;  eg: c$ 匹配abc中的c,b$不匹配abc中的b;

    2.1.12,()分组标记,内部只能使用|操作符;  eg:(abc|abd)表示abc或abd;

 

    2.1.13,\d 表示数字0到9中的一个,相当于[0-9];

    2.1.14,\w 表示单字符a-z,A-Z,0-9;相当于[a-zA-Z0-9];

    2.1.15,\D表示数字0到9之外的单字符,相当于[^0-9];  (这里的运算符是[^  ]作为整体)

    2.1.16,\w表示除了a-z和A-Z和0-9之外的字符,相当于[^a-zA-Z0-9];

 

    2.1.17,尚待自行积累;还有好多的;:)

  2.2,正则表达式的经典实例;

    2.2.1, ^[a-zA-Z0-9]+$ :  表示仅由英文字符和数字组成的字符串; [1-9]?\d  : 表示0-99;

    2.2.2, [1-9]\d{5} : 表示我国境内的6位邮政编码;

    2.2.3, ^-?\d+$ : 表示整数形式的字符串;-?这里代表的是负号是否需要;

    2.2.4,[\u4e00-\u9fa5]  :表示使用utf-8编码来匹配中文字符;

  2.3,正则表达式的表示类型;

    2.3.1,raw string类型(原生字符串类型);

        类型格式: r ' 普通字符加操作符 '  ; eg:   r' [1-9]\d{5} ' ;

           类型备注:raw string类型中转义字符就是转义字符本身的语法和意义;

    2.3.2,string类型;

         类型格式:' 此处正则表达式若是有转义字符,反斜杠重复一遍'  ;eg: ' [1-9]\\d{5}' ;

            类型备注:建议使用raw string;

 

3,正则表达式库的部分函数方法;

  3.0,正则表达式的操作参数;

    3.0.1,pattern:正则表达式表示的字符串或原生字符串;简单理解为正则表达式;

    3.0.2,string:等着被匹配出有效信息的字符串,简称带匹配字符串;

    3.0.3,maxsplit : 待匹配字符串最大分割次数;

    3.0.4,repl : 替换匹配字符串的字符串;

    3.0.5,count:替换匹配字符串的最大替换次数;

    3.0.6,flags:正则表达式使用时的控制标记;

         (1)re.I :匹配时忽略英文字符大小写的控制标记;全称re.INGORECASE;

         (2)re.M :将^操作符的开头匹配改为对字符串的每行开头匹配的控制标记;全称re.MULTILINE;

         (3)re.S :点操作符默认不匹配换行符,设置点操作符也可以匹配换行符的控制标记;全称re.DOTALL;

  3.1,re.search(pattern,string,flags=0)

      函数功能:在字符串中找到匹配正则表达式的字符串,返回match对象;

      函数例子:re.search( r'[1-9]\d{10}' , '胡犀牛13019841984' ) 

      例子意义:表示将待匹配字符串中的电话号码提取出来;(然后放到哪里呢??)      

  3.2,re.match(pattern,string,flags=0)

     函数功能:从字符串开头进行re匹配,要是开头不匹配re,则返回的match对象就是为空;

     函数例子:re.match( r'[1-9]\d{10}' , '胡犀牛13019841984')

     例子意义:待匹配字符串的开头不是电话号码,所以不匹配,返回match对象为空,如果调用当前这个空的match对象的方法就会报错;因为空对象不存在属性,也就不存在方法;

  3.3,re.findall(pattern,string,flags=0)

     函数功能:将待匹配字符串中所有能匹配的子串以列表形式返回;

     函数例子:re.findall( r'\d{11}' , '胡犀牛13019841984  钟神医 13018741874')

     例子意义:string中的两个电话号码都可以匹配,放入返回的列表类型中;

  3.4,re.split((pattern,string,maxsplit=0,flags=0)

     函数功能:将正则表达式作为分割点,按分割次数将字符串分割,其中可以匹配的子字符串每次分割的时候排除掉;返回列表类型;

     函数例子:re.split( r' \d{11}' , '胡犀牛13019841984  钟神医 13018741874',maxsplit=1)

     例子意义:分割后返回的列表类型为 [ '胡犀牛','薛神医13018741874'];分割一次,所以排除了一个电话号码,排除点作为分割点;

  3.5,re.finditer(pattern,string,flags=0)

     函数功能:将string中所有匹配子字符串作为一个迭代类型返回,其中每个迭代元素都是match对象,具有match对象的属性;

     函数例子:for num in re.finditer( r'\d{11}','胡犀牛13019841984 薛神医13018741874'):

     例子意义:匹配后的两个号码作为迭代类型,供num对象循坏调用;

  3.6,re.sub((pattern,repl, string,count=0,flags=0)

     函数功能:将匹配的子字符串替换掉,替换次数不超过count次,返回替换后的字符串;

     函数例子:re.sub(r'\d{11}','phone_num','胡犀牛13019841984 薛神医13018741874')

     例子意义:替换后的字符串为 '胡犀牛phone_num 薛神医phone_num' ;sub全称substitute;

 

4,Re库的调用形式;

  4.1,库函数调用:输入各种参数后,对库函数进行调用,将结果返回存入一个对象中;这种函数调用每次都要重新编译正则表达式,多了就慢了;

    eg: rst=re.search(r'\d{11}','胡犀牛13019841984 薛神医1318741874')

  4.2,将正则表达式通过编译函数后的结果存入对象中,这时这个对象等价于一组特定的字符串;然后去调用正则表达式的函数;减少编译次数和部分参数的传递,加快程序运行速度;

    eg:  regex=re.compile( r'普通字符和操作符')     

      #编译后的对象是re库的对象,re库的对象可以直接调用re库对象的方法;

      #方法是一种类型的函数,专门供对象调用;函数就是我们平时说的可以实现某种功能的代码块;(我也不太理解其分类原理,先这么理解);

         regex.search( '待匹配的字符串' )  返回match对象;

      regex.match('待匹配的字符串')  返回match对象;

      regex.findall('待匹配字符串')  返回列表类型;

      regex.split('待匹配字符串')  返回列表类型;

      regex.finditer('待匹配字符串')  返回迭代类型,迭代元素为match对象;

      regex.sub('待匹配字符串')  返回字符串;

 

5,Re库的match对象;

  意义:match对象是search方法,match方法和finditer方法的返回值(就是匹配的信息集合);

    (1)如果是search方法,可能string中会有多个子字符串匹配pattern正则表达式形式,但是返回的match对象中只保存第一次匹配的子字符串;

    (2)如果是match方法,match对象要么为空不存在,要么只保存第一个匹配的子字符串;

    (3)如果是finditer方法,match对象里面包含所有匹配的子字符串;要注意迭代;

  5.1,match对象的属性;

    5.1.1,  .re  :返回对象的正则表达式;返回值中有re.complie()函数,因为python开发环境认为正则表达式不算正则表达式,要经过编译之后才算;

    5.1.2,  .string  :返回对象的待匹配字符串;

    5.1.3,  .pos  :返回匹配过程从文本中搜索的开始位置;(我返回的两次都是0)

    5.1.4,  .endpos  :返回匹配过程在搜索文本中的结束位置;(我返回的两次都是string的长度)

  5.2, match对象的方法;

    5.2.1,  .group(n)  :返回被匹配的第n个子字符串;(n从0开始计数)

    5.2.2,  .start()  :返回子字符串在string中的开始位置;

    5.2.3,  .end()  :返回子字符串在string中的结束位置;

    5.2.4,  .span()  :返回子字符串在string中的开始位置和结束位置;

  5.3,5.2和4.2的方法有什么区别呢?

      4.2的方法是re库对象的方法,调用了之后可能会返回match对象;而5.2的方法是match对象的方法;

  5.4,Re库的贪婪匹配和最小匹配;

    5.4.1,贪婪匹配:正则表达式的开头匹配后,中间和结尾同时有多种子字符串匹配的方式时,默认选择最长的子字符串匹配;

       匹配例子:r=re.search(r'py*','pypyy') 匹配出来的结果是py,r=re.search(r'py*','pyy')有py和pyy两种方式匹配,匹配出来的结果是两种里面字符串最长的那种pyy;

    5.4.2,最小匹配:正则表达式的开头匹配后,中间和结尾同时有多种方式匹配时,选择最短的字符串匹配;

        最小匹配操作符:(1)  *? :表示前一个字符任意次扩展的最小匹配;

                 eg:re.search(r'py*?','pyy')表示y字符任意次扩展的最小匹配;那就0次扩展只剩p了;

                 (2)  +?  :表示前一个字符至少一次匹配的最小匹配,那就匹配一次;

                 (3)  ??  :表示前一个字符0次或1次扩展的最小匹配,那就匹配0次;

                 (4)  {m,n}?  :表示前一个字符m到n次扩展的最小匹配,那就配合字符串判断匹配几次,选个最短的;

 

posted @ 2018-12-01 13:49  caesura_k  阅读(1397)  评论(0编辑  收藏  举报