python网络爬虫学习笔记之之正则表达式

来源:互联网 发布:linux 没有telnet 编辑:程序博客网 时间:2024/05/16 07:09

正则表达式

简述

1.表达很多字符串 可以直接使用一个正则表达式

2.表达无穷多个字符串时 比如 PY+就表示P后边跟一个Y或者无穷多个Y时的情况 

3.比如一组字符串有某种特点,很难将它们枚举出来就可以使用正则表达式来进行
  比如说 一组字符串需要以'PY'开头 后续存在不多于10个字符串,后续字符串不得出现‘P’或者‘Y’ 当然你可以把所有的情况枚举出来 但是太繁琐,于是你可以使用正则表达式
 PY[^PY]{0~10} 就可以满足以上条件


正则表达式在文本处理中十分常用:
 
1.表达文本类型的特征(病毒,入侵)

2.同时查找或者替换一组字符串

3.可以匹配字符串的全部或者部分


其实正则表达式主要使用在字符串的匹配中

正则表达式的使用:

编译:将符合正则表达式语法的字符串转换成正则表达式的特征,正则表达式其实就是某一种语法格式,但是在程序中我们必须使用字符串的格式 来表达它

我们可以认为编译后的特征与一组字符串进行对应


正则表达式的语法

正则表达式由字符和操作符构成

正则表达式的常用操作符:
 .   表示任意单个字符
[]  字符集,对单个字符给出取值范围   [abc]表示a b c  [a-z] 表示a到z单个字符
[^]非字符集 对单个字符给出排除范围   [^abc]表示非a b c 的的单个字符
* 表示0 或者无限次扩展  abc*表示 ab abc abcc  abcccc等
+表示1或者无限次扩展 abc+ 表示abc abcc  abccc等
?表示0或者1次扩展 abc?表示ab abc
|表示左右任一个    abc|def 表示abc或者是def
{m}表示扩展前一个字符m次    ab{2}c 表示abbc
{m,n}表示扩展前一个字符m到n次 (含n次) ab{1,2}c表示abc abbc
^匹配字符串的开头   ^abc 表示abc且在一个字符串的开头
S匹配字符串的结尾  abcS表示abc且在一个字符串的结尾
()分组标记 内部只能使用|操作符 比如(abc)表示abc  (abc|def)标识abc 或者 def
\d表示数字  等价于0-9
\w表示单词字符 等价于{A-Z a-z 0-9}

比如说一段IP地址  0~255 四个前面的数字都是这个范围 那我们该如何表达这个0~255数字呢
其实需要分成四个部分分别写

首先0~99  [1-9]?\d  (注意十位和个位是不一样的 )
100~199    1[0-9]{2}
200~249    2[0-4]\d
250~255    25[0-5]
所以一段IP地址可以表示为
(([1-9]?\d | 1[0-9]{2} | 2[0-4]\d | 25[0-5]).){3} (([1-9]?\d \1[0-9]{2} | 2[0-4]\d | 25[0-5]))   之所以前三个和后一个 分开是因为前三个后边都有.  最后一个后面是没有点的   其他数值部分表示都是一样的




RE库的介绍

RE库是python的标准库,主要是用来匹配字符串

正则表达式的表示类型

raw  string(原生字符串类型)

re库采用raw string 类型表示正则表达式,表示为 r'text'
例如: 邮政编码 : r'[1-9]\d {5}'   总共六位

原生的字符串类型和一般的字符串类型所不同的是 前面要加一个r
 原生字符串类型是不包括转义字符的字符串

原生字符串中间的\不被解释为转义字符
如果一个字符串中间出现了转义字符时 如果使用字符串进行表示那么所有的转义字符前面都要加上一个\ 很麻烦啊

所以我们建议  当正则表达式包含转义符时 我们使用raw string   只需在字符串前面加一个r即可


RE库的主要功能函数

re.search()  在一个字符串中搜索匹配正则表达式的第一个位置,返回match对象

re.match()  在一个字符串的开始位置匹配正则表达式,返回match对象

re.findall() 搜索字符串 以列表类型返回全部可以匹配的字串

re.split() 将一个字符串按照正则表达式匹配结果进行分割,返回列表类型

re.finditer() 搜索字符串,返回一个匹配结果的迭代类型,每个迭代类型都是match对象   ???没看懂啊

re.sub() 在一个字符串中替换所有的匹配正则表达式的字串,返回替换后的字符串


下面详细介绍这六个函数的具体使用:

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

pattern:正则表达式的字符串或者原生字符串表示

string 待匹配的字符串

flags  正则表达式使用时的控制标记   主要介绍三种: re.I    忽略正则表达式的大小写,[A-Z]也可以匹配小写字符
                                                                                               re.M 正则表达式中的^操作符能够将给定字符串的每行当作匹配的开始
                                                                                               re.S 正则表达式中的.可以匹配所有字符,默认的re库中.操作符可以匹配除了换行符以外的所有字符



import re 
match=re.search(r'[1-9]\d{5}','BIT 100082')
if match:
    print(match.group(0))                                            #然而并看不懂这是什么操作







re.match(pattern,string,flags=0)   从一个字符串的开始位置起匹配正则表达式 返回match对象

               pattern:正则表达式的字符串或者原生字符串表示

                string 待匹配的字符串

              flags  正则表达式使用时的控制标记 


import  re
match=re.match(r'[1-9]\d{5}','xuanxuan 188834')
if match:
    print(match.group(0))




match其实是空的 ,因为正则表达式我们给的是一个邮政编码,而给出的字符串的开头确是一个字符串 因此正则表达式的匹配结果是空的,因此match并不是一个有匹配结果的变量,而是一个空的,因此对于一个空变量而言你去调用一个group方法肯定是不对的





re.findall(pattern,string,flags=0)  搜索字符串,以列表类型返回全部能匹配的字串  里面的参数有search 和match是一样的 ,但是要注意search 和 match返回的都是match类型   而 findall返回的确是列表类型
 import re
ls=re.findall('[1-9]\d{5}','xuanxuan122345  keke857845')
if ls:
    print(is)







re.split(pattern,string,maxsplit,flags=0) 将一个字符串按照正则表达式匹配结果进行分割,返回列表类型

maxsplit表示最大分割数 就是分成几部分 就是把后面的字符串中与正则表达式匹配的部分去掉,其他的进行分割

import re 
re.split(r'[1-9]'\d{5},'xuanxuan122348 keke473845')


加入maxsplit参数 就会 考虑分成几部分


比如这里就是只匹配第一个,其他的作为一个整体打印出来


re.finditer(pattern,string,flags=0)  搜索字符串,返回一个匹配结果的迭代类型,每个迭代元素都是match对象

import re 
for  m  in re.finditer('[1-9]\d{5}','xuanxuan283745 keke3475495')
      if m:
         print(m.group(0))



re.sub(parttern,repl,string,count=0,flags=0)
在一个字符串中替换所有匹配正则表达式的字串 返回替换后的字符串


import  re 
sub=re.sub(r'[1-9]\d{5}','zipcode','xuanxuan128728 kekexua384785')




pat=re.compile(r'[1-9]\d{5}')     pat  才是一个正则表达式
rst=pat.search('Bit 239849')
recompile(pattern,flags)  pattern 正则表达式的字符串或者原生字符串对象 他才是真正的正则表达式 他可以直接调用re的六个函数‘

经过conpile以后的对象就可以使用正则表达式的方法 与re库提供的六个方法是一样的


注意:


re.findall(r'[1-9]\d{5}','xuanxuan928344 keke394389')’会返回一个列表类型{928344 394389}


re.finditer() 是返回一个迭代类型 需要结合for循环来进行
for match  in re.finditer(r'[1-9]\d{5}','xuanxuan934839 keke739456'):
        if match:
                 print(match.group(0))
就会输出: 
934839 
739456


而不是一个列表list的!!!