• 正则表达式


    1.1正则表达式

    正则表达式和字符串

    在编程里字符串是涉及到最多的一种数据结构,对字符串操作的需要几乎无处不在。

    比如判断一个字符串是否合法的email地址,虽然可以提取@前面和后面的子串,又再分别判断是否是单词和域名,但这样很麻烦,而且代码难以复用。

    正则表达式式一种用来模糊匹配字符串的方法,它的设计思想是用一种描述性的语言来给字符串定义一个规则,凡是符合规则的字符串,我们就认为它“匹配了”,否则该“没有匹配到该字符串”

    需要导入正则的模块

    import re

    字符匹配(普通字符,元字符)

    1.普通字符:数字字符和英文字母和自身匹配

    2.元字符:.  ^  $  *  + ?  {}  [] () |  

    re.方法("规则","匹配的字符串")

    .  匹配任意一个字符,除了 换行符

    1 #findall查找所有字符
    2 print(re.findall("a.","ssdfyildazvdfeewrae"))  #['az', 'ae']  匹配a后面的任意一个字符
    3 print(re.findall("a..","ssdfyildazvdfeewrae"))  #['azv']    匹配a后面的任意两个个字符
    .方法

    ^  匹配以什么开头的字符

    1 re_str = "ssdfyildazvdfeewrae"
    2 print(re.findall("^s..",re_str))  # ['ssd']  #匹配以s开头后面两个任意字符
    3 print(re.findall("^aa",re_str)) #[]  #匹配aa开头
    ^方法

    $  匹配以什么结尾

    1 re_str = "ssdfyildaaazvdfeewrae"
    2 print(re.findall("ee$",re_str))  #[]
    3 print(re.findall("ae$",re_str))  #['ae']
    $方法

    *  字符*   匹配前面的字符 出现的0-无穷次

     1 import re
     2 
     3 re_str = "ssdfyilddddkaaazvdfeewrae"
     4 
     5 # print(re.findall("*",re_str)) #报错,要加匹配字符
     6 print(re.findall("d*",re_str))#匹配d出现的0到无穷次 没有,也匹配上了
     7 # ['', '', 'd', '', '', '', '', 'dddd', '', '', '', '', '', '', 'd', '', '', '', '', '', '', '', '']
     8 print(re.findall("ld*k",re_str)) #['lddddk']   #匹配ld*k  匹配*前面的d字符出现的0到无穷次
     9 
    10 print(re.findall("sd*",re_str)) #['s', 'sd']   匹配sd*  d出现的0到无穷次
    11 print(re.findall("ras*",re_str)) #['ra']    匹配ras*  res中s出现的0到无穷次
    *方法

    +  字符+  匹配前面的一个字符出现的1-无穷次 ,最少有1次

    1 re_str = "ssdfyilddddkaaazvddfeewrae"
    2 
    3 print(re.findall("dd+",re_str)) #['dddd']  匹配dd+中d出现的一到无穷次
    4 print(re.findall("d+",re_str))  #['d', 'dddd', 'dd']  匹配d+中d出现的一到无穷次
    + 用法

    ?  字符?  匹配前面字符重复零次或一次

    1 name = "asdfqwzerzxcv"
    2 print(re.findall("x?",name)) #匹配x字符出现的0次或者1次
    3 # ['', '', '', '', '', '', '', '', '', 'x', '', '', '']
    4 print(re.findall("zx?",name))  #['z', 'zx']  #匹配zx  x出现的0次或者1次
    ?用法 

    注:* + ?等都是贪婪匹配,也就是尽最大能力去匹配,匹配字符后面加?变成了惰性匹配,一般都是用贪婪匹配

    1 name = "asdfqwzerzxcv"
    2 print(re.findall("zx*?",name))  #['z', 'z'] #惰性匹配,最小匹配原则
    惰性匹配

    {}  字符{n} 匹配字符出现的n次,字符{1,n}匹配字符出现1到n次

    1 name = "aasdfqwzerzxcvaaaavv"
    2 print(re.findall("aa{1,5}",name)) #['aa', 'aaaa']  #匹配aa a出现的一到5次之间
    3 print(re.findall("aa{1,5}v",name)) #['aaaav']   #匹配aa{1,5}v  ,a出现的一到5次之间
    4 print(re.findall("a{5}",name))  #[] 只匹配a出现的5次
    5 print(re.findall("a{3}",name))  #['aaa'] 只匹配a出现的3次
    {}方法

    []  字符[字符集]  匹配字符集中的某一个符号

    1 name = "aasdfqawzerzxcvaaaavv"
    2 print(re.findall("a[a]",name))  #['aa', 'aa', 'aa'] #只匹配aa
    3 print(re.findall("a[a]a",name))  #['aaa'] #只匹配aaa
    4 print(re.findall("f[.q]",name)) #['fq']#匹配f.或者fq
    5 print(re.findall("f[.q]b",name)) ##匹配[] f.b或者fqb
    []方法

    [字符集]  里面的字符集都是普通字符,除了-,^.

    - ^ 这三个符号在字符集有特殊功能的符号,其它都是普通字符

     1 [] 字符集中- 的方法    -  组成一个连接范围的数字
     2 name = "aasdfqawzerzxcvaaaavv"
     3 print(re.findall("a[a-z]",name))#['aa', 'aw', 'aa', 'aa']    #匹配a[a到z]的任意字符
     4 alp_num = "a12a 34a5567asdfqwer"
     5 print(re.findall("a[0-9 a-z]",alp_num)) #['a1', 'a ', 'a5', 'as']#空格也是普通字符
     6 print(re.findall("a[0-9a-zA-Z]",alp_num)) #['a1', 'a5', 'as']  
     7 
     8 
     9 []字符集中^的方法    ^非,把相反的给找出来
    10 name = "aasdfqawzerzxcvaaaavv"
    11 tes = "abc"
    12 print(re.findall("[^0-9]",tes)) #['a', 'b', 'c']    #把非0到9数字给匹配出来
    13 print(re.findall("a[^0-9]",name))#['aa', 'aw', 'aa', 'aa']  把匹配a字符集中非0到9数字给匹配出来
    14 
    15 
    16 []字符集中的方法,把普通的特殊字符变得有意义
    17 aa = "advca11234"
    18 print(re.findall("[d]",aa))    #['1', '1', '2', '3', '4'] #是转义字符,把普通字符,实现特殊的功能
    [-] [^] []的方法

      元字符的转义符

    反斜杠后面跟元字符去除特殊功能,比如.  *

    反斜杠后边跟普通字符实现特殊功能比如d

    d  匹配任何十进制数;它相当于类 [0-9]。
    D 匹配任何非数字字符;它相当于类 [^0-9]。
    s  匹配任何空白字符;它相当于类 [ fv]。
    S 匹配任何非空白字符;它相当于类 [^ fv]。
    w 匹配任何字母数字字符;它相当于类 [a-zA-Z0-9_]。
    W 匹配任何非字母数字字符;它相当于类 [^a-zA-Z0-9_]
      匹配一个特殊字符边界,比如空格 ,&,#等

    1 bb = "axs1233_sa _%"
    2 print(re.findall("d",bb)) #['1', '2', '3', '3']
    3 print(re.findall("D",bb)) #['a', 'x', 's', '_', 's', 'a', ' ', '_', '%']
    4 print(re.findall("s",bb)) #[' ']
    5 print(re.findall("S",bb)) #['a', 'x', 's', '1', '2', '3', '3', '_', 's', 'a', '_', '%']
    6 print(re.findall("w",bb))#['a', 'x', 's', '1', '2', '3', '3', '_', 's', 'a', '_']
    特殊字符的转义
    1 cal = "()(_)(*)(s)12+(28*10+5+2-8-3*(2-1))"
    2 print(re.findall("()",cal)) #['()'] #只匹配普通字符的括号()
    3 print(re.findall("([w])",cal)) #['(_)', '(s)'] #匹配(任意一个字母数字_)
    简单的转义
    1 gan = "\"
    2 print(gan)#  python解释器中字符串\,才表示一个
    3 print(re.findall("\\",gan)) #['\'],其实就是一个

    r"字符串"  表示原始字符串(r---> raw string)

    |  字符a|字符b    匹配字符a或者字符b 的表示或得方法 

    1 ss = "abs,youbyy"
    2 print(re.findall("a|b",ss))#['a', 'b', 'b']
    3 print(re.findall("ou|y",ss)) #['y', 'ou', 'y', 'y']
    | 或方法

    ()  (字符)优先匹配字符里面的内容。

    1 tot = "asdasdasdasd"
    2 print(re.findall("(asd)*",tot)) #['asd', ''] #0到无穷匹配
    3 print(re.findall("(asd)?",tot)) #['asd', 'asd', 'asd', 'asd', ''] #0到1次匹配asd
    4 print(re.findall("(asd)+",tot))  #['asd'] #1到无穷匹配
    5 print(re.findall("(asd)",tot))   #['asd', 'asd', 'asd', 'asd']
    () 的方法

    re模块的常用方法

    1.re.findall()

    1 import re
    2 print(re.findall("a",bb)) #返回所有满足匹配条件的结果,放在列表里

    2.re.match()

    语法

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

    pattern 匹配的正则表达式
    string 要匹配的字符串。
    flags 标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。

    匹配成功re.match方法返回一个匹配位置的对象,否则返回None。(从最开始匹配) 

    我们可以使用group(num)或groups()匹配对象函数来获取匹配表达式。 

    group(num=0) 匹配的整个表达式的字符串,group() 可以一次输入多个组号,在这种情况下它将返回一个包含那些组所对应值的元组。
    groups() 返回一个包含所有小组字符串的元组,从 1 到 所含的小组号。
     1 bb = "advca11234"
     2 print(re.match("12",bb))  #None  不是开始位置匹配
     3 print(re.match("adv",bb)) #开始位置匹配,返回匹配的位置对象
     4 #<_sre.SRE_Match object; span=(0, 3), match='adv'>
     5 
     6 print(re.match("adv",bb).span()) #(0, 3) 获取匹配对象的位置
     7 #
     8 print(re.match("adv",bb).group()) # adv  #获取匹配对象的结果内容
     9 print(re.match("adv",bb).groups()) #() #获取模型中匹配到的分组结果
    10 print(re.match("adv",bb).groupdict()) #{}  #获取模型中匹配到的分组结果 {}
    match

    3re.search方法

    re.search扫描整个字符串并返回第一成功的匹配

    用法:re.search(pattern, string, flags=0)

    匹配成功re.search方法返回一个匹配的对象,否则返回None

    我们可以使用group(num)或groups()匹配对象函数来获取匹配表达式

     1 bb = "advca11234"
     2 print(re.search("d+",bb))
     3 #返回一个函数匹配对象  span 是匹配的位置   math是匹配对象的内容
     4 #<_sre.SRE_Match object; span=(5, 10), match='11234'>
     5 
     6 info = "yj18yj18yj19"
     7 print(re.search("(?P<name>[a-z]+)",info).group("name")) #yj  #得到特定的分组信息内容
     8 print(re.search("(?P<name>[a-z]+)(?P<age>d+)",info).group("name","age"))#('yj', '18') #得到特定的分组信息 ,以元祖返回
     9 print(re.search("(?P<name>[a-z]+)(?P<age>d+)",info).group())# yj18 #获取分组信息的所有内容、
    10 print(re.search("(?P<name>[a-z]+)(?P<age>d+)",info).groups()) #('yj', '18')
    11 #得到分组的所有信息,以元祖返回
    12 print(re.search("(?P<name>[a-z]+)(?P<age>d+)",info).groupdict())# yj18 #获取分组的所有内容、
    13 #{'name': 'yj', 'age': '18'} 以字典返回,分组信息
    14 print(re.search("(?P<name>[a-z]+)(?P<age>d+)",info)) #得到是分组的对象
    15 
    16 #?P<name> 给信息做一个分组
    search方法

    re.match与re.search的区别

    re.match只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,函数返回None;

    而re.search匹配整个字符串,直到找到一个匹配。

    4re.sub()   用于替换字符串中的匹配项。

    语法:re.sub(pattern, repl, string, count=0)

    • pattern : 正则中的模式字符串。
    • repl : 替换的字符串,也可为一个函数。
    • string : 要被查找替换的原始字符串。
    • count : 模式匹配后替换的最大次数,默认 0 表示替换所有的匹配。
    1 phone = "110-119-911-112"
    2 print(re.sub(r"-"," ",phone,count=2))#检索字符串的-,把前两个替换成空格
    3 #110 119 911-112
    re.sub方法

    5re.split() 分割字符串

    语法:split(pattern, string, maxsplit=0, flags=0):

    maxsplit : 模式匹配后分割的最大次数,默认 0 表示替换所有的匹配。

    1 alp = "a b c  d"
    2 print(re.split("s+",alp,maxsplit=2)) 
    3 #['a', 'b', 'c  d'] #分割前两个的字符串个空格,以列表形式返回
    re.split方法

    6re.finditer() 方法,把找到的结果做成一个迭代器对象,取值用next()

    语法和findall一样

    1 phone = "110-119-911-112"
    2 print(re.finditer("d+",phone))#<callable_iterator object at 0x0000009E83BCAE10>
    3 te = re.finditer("d+",phone)
    4 print(next(te).group()) #110
    5 print(next(te).group()) #119
    6 print(next(te).group()) #911
    re.finditer方法

    字符类

    [0-9] 匹配任何数字。类似于 [0123456789]
    [a-z] 匹配任何小写字母
    [A-Z] 匹配任何大写字母
    [a-zA-Z0-9] 匹配任何字母及数字
    [^aeiou] 除了aeiou字母以外的所有字符
    [^0-9] 匹配除了数字外的字符

     特殊转义字符类

    实例描述
    . 匹配除 " " 之外的任何单个字符。要匹配包括 ' ' 在内的任何字符,请使用象 '[. ]' 的模式。
    d 匹配一个数字字符。等价于 [0-9]。
    D 匹配一个非数字字符。等价于 [^0-9]。
    s 匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ f v]。
    S 匹配任何非空白字符。等价于 [^ f v]。
    w 匹配包括下划线的任何单词字符。等价于'[A-Za-z0-9_]'。
    W 匹配任何非单词字符。等价于 '[^A-Za-z0-9_]'。
  • 相关阅读:
    《一起》个人进展——Day05
    《一起》个人进展——Day04
    《一起》个人进展——Day03
    《一起》个人进展——Day02
    《一起》个人进展——Day01
    this
    java_流
    input _文本框回车或者失去光标触发事件
    removeAll
    SysLog简介和java操作实例
  • 原文地址:https://www.cnblogs.com/keme/p/6181379.html
Copyright © 2020-2023  润新知