zoukankan      html  css  js  c++  java
  • 正则表达式

    1、正则表达式基本概念

    1、学习正则表达式
    2、学习使用re模块来操作正则表达式
    3、正则规则处理字符串有特殊的优势
    可以参考《正则指引》这本书
    正则表达式其实跟python没什么关系,只是字符串的处理

    字符组 : [字符组]
    在同一个位置可能出现的各种字符组成了一个字符组,在正则表达式中用[]表示
    字符分为很多类,比如数字、字母、标点等等。
    假如你现在要求一个位置"只能出现一个数字",那么这个位置上的字符只能是0、1、2...9这10个数之一。

    写范围:不要垮范围进行编辑,因安装ASCII的顺序中,范围之间是有其它字符的
    ^ 和$配对使用
    | :从左边匹配开始,
    正则分组:()用小括号表示

    匹配多个字符:dddddd这样可以匹配6个数字
    d* :匹配0次或多次,贪婪的匹配
    d+ :匹配一次或者多次
    所有量词都要放在正则规则的后面:且量词只约束紧跟着它的规则

    1、1常规匹配范围举例

    
    
    正则
    待匹配字符
    匹配
    结果
    说明
    [0123456789]
    8
    True
    在一个字符组里枚举合法的所有字符,字符组里的任意一个字符
    和"待匹配字符"相同都视为可以匹配
    [0123456789]
    a
     
    False
     
    由于字符组中没有"a"字符,所以不能匹配
     
    [0-9]
     
    7
     
    True
     
    也可以用-表示范围,[0-9]就和[0123456789]是一个意思
     
    [a-z]
     
    s
     
    True
     
    同样的如果要匹配所有的小写字母,直接用[a-z]就可以表示
     
    [A-Z]
     
    B
     
    True
     
    [A-Z]就表示所有的大写字母
     
    [0-9a-fA-F]
     
    e
     
    True
     
    可以匹配数字,大小写形式的a~f,用来验证十六进制字符

    1.2 字符

    元字符
    匹配内容
    . 匹配除换行符以外的任意字符
    w 匹配字母或数字或下划线(word)
    s 匹配任意的空白符(space)
    d 匹配数字(digit)
    匹配一个换行符
    匹配一个制表符
     匹配一个单词的结尾
    ^ 匹配字符串的开始
    $ 匹配字符串的结尾
    W
    匹配非字母或数字或下划线
    D
    匹配非数字
    S
    匹配非空白符
    a|b
    匹配字符a或字符b
    ()
    匹配括号内的表达式,也表示一个组
    [...]
    匹配字符组中的字符
    [^...]
    匹配除了字符组中字符的所有字符

     1.3量词

    量词
    用法说明
    * 重复零次或更多次
    + 重复一次或更多次
    ? 重复零次或一次
    {n} 重复n次
    {n,} 重复n次或更多次
    {n,m} 重复n到m次

     1.4  . ^ $的使用

     正则表达式  待匹配字符  匹配结果    说明
     张.  张三张四张五  

    张三
    张四
    张五

     匹配所有“张.”的字符
     ^张.  张三张四张五  张三  只从开头匹配“张.”的字符
    张.$ 张三张四张五飞 匹配不上 只匹配以“张.”结尾的字符
     张.$  张三张四张五  张五  只匹配以“张.”结尾的字符

     1.5  * + ? { }

    正则   待匹配字符 匹配结果 说明
    张.? 张三张四的张五飞名字

    张三
    张四
    张五

    ?表示重复零次或一次,即只匹配"张"后面一个任意字符
    张.* 张三张四的张五飞名字

    张三张四的张五飞名字

    *表示重复零次或多次,即匹配"张"后面0或多个任意字符
    张.+ 张三张四的张五飞名字 张三张四的张五飞名字
    +表示重复一次或多次,即只匹配"张"后面1个或多个任意字符
    张.{1,2} 张三张四的张五飞名字

    张三张
    张五飞

    {1,2}匹配1到2次任意字符

    注意:前面的*,+,?都是贪婪匹配,它们是尽可能进行匹配,后面加上?号使得它们变成惰性匹配

    正则   待匹配字符 匹配结果 说明
    张.?? 张三张四的张五飞名字



    惰性匹配:其实就是按满足条件的最小情况来匹配
    张.*? 张三张四的张五飞名字



     
    张.+? 张三张四的张五飞名字

    张三
    张四
    张五

     
    张.{1,2}? 张三张四的张五飞名字

    张三
    张四
    张五

     

    1.6 字符集[][^]

    正则 待匹配字符 匹配结果 说明
    张[三四的五飞名字]* 张三和张四的和张五飞名字

    张三
    张四的
    张五飞名字

    表示匹配"张"字后面[三四的五飞名字]的字符任意次
    张[^和]* 张三和张四的和张五飞名字

    张三
    张四的
    张五飞名字

    表示匹配一个不是"和"的字符任意次
    [d] 5566AAC12D4e

    5
    5
    6
    6
    1
    2
    4

    表示匹配任意一个数字
    [d]+ 5566AAC12D4e

    5566
    12
    4

    表示匹配任意个数字,匹配到3个结果

    1.7 分组 ()与 或 |[^]

    我们这里以身份证的号码为例进行说明。身份证的组成:要么是15位,要么是18位;如果是15位,那么全部是数字,

    且开始位不为0;如果是18位,那么开始位不为0,第18位要么是数字或x,其它位为数字。

    正则 待匹配字符 匹配结果 说明
    ^[1-9]d{13,16}[0-9x]$ 123456789012345678 123456789012345678 可以匹配到正常的身份证号码
    ^[1-9]d{13,16}[0-9x]$ 12345678901234567 12345678901234567 17位也可以匹配到,这不符合身份证要么15位要么18位的要求
    ^[1-9]d{14}(d{2}[0-9x])?$ 1234567890123456 没有匹配到
    现在不会匹配错误的身份证号了
    ()表示分组,将d{2}[0-9x]分成一组,就可以整体约束他们出现的次数为0-1次
    ^([1-9]d{16}[0-9x]|[1-9]d{14})$ 12345678901234567x 12345678901234567x 如果是或的匹配规则,那么要先把匹配长字符串的正则放在前面,匹配短字符放在后面,这样避免短的字符正则匹配18位字符时候,是以前15位来判定,这样就会造成后面的数据可能是错误的而判定为错误号码。

     1.8  转义符

    在python中,无论是正则表达式,还是待匹配的内容,都是以字符串的形式出现的,在字符串中也有特殊的含义,本身还需要转义。所以如果匹配一次" ",字符串中要写成'\n',那么正则里就要写成"\\n",这样就太麻烦了。这个时候我们就用到了r' '这个概念,此时的正则是r'\n'就可以了。

    正则 待匹配字符 匹配结果 说明
    False 正则表达式中是有特殊意义的字符,如果要匹配 ,用 无法匹配
    \n True 转义之后变成\,即可匹配
    “\\n” "\n" True 字符串中的也需要转义,所以每一个字符串又要需要转义一次
    r'\n' r' ' True 在字符串之前加r,让整个字符串不转义

     1.9 贪婪匹配

    贪婪匹配:在满足匹配时,匹配尽可能长的字符串,默认情况下,采用贪婪匹配

    正则 待匹配字符 匹配结果 说明
    <.*> <script>...<script> <script>...<script> 默认为贪婪匹配模式,会匹配尽量长的字符串
    <.*?>   r'd'

    <script>

    <script>

    加上?,将贪婪匹配模式转为非贪婪匹配模式,会匹配尽量短的字符串。

    下面是几个常用的非贪婪匹配模式

    正则   说明
    *? 重复任意次,但尽可能少重复
    +? 重复1次或更多次,但尽可能少重复
    ?? 重复0次或1次,但尽可能少重复
    {n,m}? 重复n到m次,但尽可能少重复
    {n,}? 重复n次以上,但尽可能少重复









    .*?的用法
    . 是任意字符
    * 是取0至无限长度
    ?是非贪婪模式
    这三个合在一起就是取尽量少的任意字符,但一般情况下不这么用,更多的是用在: .*?x 这一情况
    就是取前面任意长度的字符,直到一个x出现。

    2、re模块
    1 ret = re.findall('p','peng p123')
    2 print(ret)
    1 ['p', 'p']
    2 
    3 返回所有满足匹配条件的结果,并把结果放在列表里面。
    View Code
    1 ret = re.search('ab','pengab juna456').group()
    2 print(ret)
    1 ab
    2 
    3 search()函数会在字符串中查找模式匹配,只要找到第一个匹配然后返回一个包含匹配信息的对象,该对象可以通过调用
    4 group()方法得到匹配的字符串,如果没有匹配的字符,则返回none;
    View Code
    1 ret = re.match('a','abcpengadb').group()
    2 print(ret)
    1 a
    2 
    3 在字符串开始处进行匹配,开始处有则匹配上,无则报错
    View Code
    1 ret = re.split('[ab]','pengagbcd')
    2 print(ret)
    1 ['peng', 'g', 'cd']
    2 
    3 先按'a'进行分割,得到'peng''gbcd',然后再按b进行分割,得到peng、g、cd
    View Code
    1 ret = re.split('[abc]','pengagb66cd')
    2 print(ret)
    View Code
    1 ['peng', 'g', '66', 'd']
    View Code
     
    1 ret = re.sub('d','H','peng3jun555fei89',4)
    2 print(ret)
    1 pengHjunHHHfei89
    2 
    3 把数字替换为H,最后面的参数表示替换多少个
    View Code
    1 ret = re.subn('d','A','peng321jun6fei907')
    2 print(ret)
    1 ('pengAAAjunAfeiAAA', 7)
    2 
    3 把数字全部替换为A,并返回元组(替换的结果,替换了多少次)
    View Code
    1 obj = re.compile('d{3}')
    2 ret = obj.search('a55bc345pe5678n22g').group()
    3 print(ret)
    1 345
    2 
    3 把正则表达式编译为一个正则表达式对象,规格是要匹配3个字符,然后调用正则表达式对象调用search,
    View Code
    1 ret = re.finditer('d','peng45j3un345f987ei')
    2 print(ret)
    3 print(next(ret).group())
    4 print(next(ret).group())
    5 print(next(ret).group())
    6 print([i.group() for i in ret])
    1 <callable_iterator object at 0x0000000002138A20>
    2 4
    3 5
    4 3
    5 ['3', '4', '5', '9', '8', '7']
    6 
    7 
    8 返回一个存放匹配结果的迭代器
    View Code
    1 #findall()优先级查询
    2 
    3 ret = re.findall('www.(sina|ifeng).com','www.ifeng.com')
    4 print(ret)
    5 
    6 ret = re.findall('www.(?:sina|ifeng).com','www.ifeng.com')
    7 print(ret)
    1 ['ifeng']
    2 ['www.ifeng.com']
    3 
    4 #这是因为findall()会优先把匹配结果内容返回,如果要想匹配结果,取消权限即可
    View Code
    1 #split的优先级查询
    2 ret = re.split('d+','peng456j983u3n33fei1')
    3 print(ret)
    4 
    5 ret = re.split('(d+)','peng34jun3f9ei567')
    6 print(ret)
    1 ['peng', 'j', 'u', 'n', 'fei', '']
    2 ['peng', '34', 'jun', '3', 'f', '9', 'ei', '567', '']
    3 
    4 #在匹配部分加上()转换所切除来的结果是不同的
    5 #没有()的就不保留所匹配的项,但是有()的能够保留匹配的项
    6 #这个在某些要保留匹配部分的使用过程中非常重要
    View Code
     
  • 相关阅读:
    KnockoutJS 3.X API 第五章 高级应用(4) 自定义处理逻辑
    KnockoutJS 3.X API 第五章 高级应用(3) 虚拟元素绑定
    KnockoutJS 3.X API 第五章 高级应用(2) 控制后代绑定
    KnockoutJS 3.X API 第五章 高级应用(1) 创建自定义绑定
    KnockoutJS 3.X API 第四章(14) 绑定语法细节
    KnockoutJS 3.X API 第四章(13) template绑定
    KnockoutJS 3.X API 第四章 表单绑定(12) selectedOptions、uniqueName绑定
    KnockoutJS 3.X API 第四章 表单绑定(11) options绑定
    KnockoutJS 3.X API 第四章 表单绑定(10) textInput、hasFocus、checked绑定
    KnockoutJS 3.X API 第四章 表单绑定(9) value绑定
  • 原文地址:https://www.cnblogs.com/xiaofei1106/p/10799033.html
Copyright © 2011-2022 走看看