Python字符串—正则表达式

        Python语言的正则表达式功能由标准包re提供。利用正则表达式可以较容易地实现许多复杂字符串操作。

        Python正则表达式采用字符串字面量的形式描述(即引号括起的字符 序列)。从Python语言的角度看它们就是普通的字符串,但在用于re包提供的一些特殊操作时,一个具有正则表达式形式的字符串代表一个字符串模式,描述了一个特定的字符串集合。这类操作就是re包提供的正则表达式匹配操作。

原始字符串

        首先介绍原始字符串(raw string)的概念。原始字符串是在Python里书写字符串文字量的一种形式,这种文字量的值和普通文字量一样,就是str类型的字符串对象。

原始字符串的形式在普通字符串文字量前加r或R前缀,例如:

R"abcdefg"         r"C:\courses\python\progs"

        原始字符串只有一点特殊,就是其中的反斜线字符“\”不作为转义符,在相应字符串对象(str对象)里原样保留。但位于单 / 双引号前的反斜线符号仍作为转义符。

        Python语言引入原始字符串只是为了使一些字符串文字量的写法略微简单。例如,描述Windows文件路径的原始字符串 r"C:\courses\python\progs",如果用普通文字量的形式,应该写为“C:\\courses\\python\\progs”,其中的反斜线需要双写,比较麻烦。

元字符

正则表达式包re规定了一组特殊字符,称为元字符。在匹配字符串时,它们起着特殊的作用。元字符一共有14个:

.  ^  $  *  +  ?  \  |  {  }  [  ]  (  )

        应该注意的是,在(普通)字符串里,这些字符都是普通字符(“\”除外),只有在把字符串作为正则表达式,用于re包提供的一些特殊操作时,这些字符才有特殊意义。下面将把作为正则表达式使用的串称为模式串,将非特殊字符称为常规字符,它们是描述正则表达式的基础。

主要操作

首先介绍re包提供的几个操作。下面的函数中,参数表里的pattern表示模式串(描述正则表达式的字符串),string表示被处理的字符串,repl表示替换串。

  • 生成正则表达式对象:re.compile(pattern, flag=0)
  • 检索:re.search(pattern, string, flag=0)
  • 匹配:re.match(pattern, string, flag=0)
  • 分割:re.split(pattern, string, maxsplit=0, flags=0)
  • 找出所有匹配串:re.findall(pattern, string, flags=0)

示例:

r1 = re.compile("abc")         # re.compile('abc')
re.search(r1, "aaabcbcbabcb")  # 
re.match(r1, "aaabcbcbabcb")   # None
re.findall("abc", "aaabcbcbabcb") # ['abc', 'abc']

字符组

  • 字符组描述符 [...] :
    与方括号中列出的字符序列中的任一字符匹配。字符组里字符的排列顺序并不重要。例如,[abc]可以与字符a或b或c匹配。还有其他形式,1、区间形式是(顺序列出字符形式的)字符组描述的缩写形式,例如,字符组[0-9]匹配所有十进制数字字符[0-9a-zA-Z]能匹配左右的数字和字母。2、特殊形式[^...]表示对 ^ 之后列出的字符组求补,即这种字符组表达式与所有未列出在括号里的字符匹配,例如[^0-9]匹配非十进制数字的所有字符。

重复

实际中经常需要用到一个模式的重复匹配,可能是任意多次的重复匹配或规定次数的重复匹配。

  • 重复描述符:
    re正则表达式的基本重复运算符是“*”,模式a*要求匹配模式a能匹配的字符串的0次或任意多次重复。还有一个与“*”略微不同的重复运算符“+”,表示其作用模式的1次或多次重复。
    re.split('[ ,]*', "1 2, 3   4, ,  5")  # 任意多个空格和逗号切分
    re.split("a*", "abbaaabbdbbabbababbabb")  # 结果 ['', 'bb', 'bbdbb', 'bb', 'b', 'bb', 'bb']
    # Python3测试发现通配符*无法得到预期结果,使用+号可以
    re.split('[ ,]+', "1 2, 3   4, ,  5")  # 任意多个空格和逗号切分
    re.split("a+", "abbaaabbdbbabbababbabb")  # 结果 ['', 'bb', 'bbdbb', 'bb', 'b', 'bb', 'bb']
  • 可选描述符:“?”是可选(片段)描述符表示,例如,a?表示要求与a匹配的字符串的0或1次重复匹配。
  • 重复次数描述符:确定次数的重复用{n}描述,a{n}与a匹配的串的n次重复匹配。例如,'(010-)?[2-9][0-9]{7}',表示总以010-开始,随后是数字2到9,再后是7个十进制数字。
  • 重复次数的范围描述符:范围用{m,n}描述。例如,a{3,7}与3到7个a构成的串匹配;go{2,5}gle与google、gooogle、goooogle、gooooogle匹配。
     

选择

  • 选择描述符:描述符“|”描述与两种或多种情况之一的匹配。
    例如:
    a|b|c: 匹配a或者b或者c
    0|[1-9]\d*: 匹配Python的十进制证书(Python负号看作运算符,非0整数不能以0开头)
    0\d{2}-\d{8}|0\d{3}-\d{7,8}:匹配国内固定电话号码的模式,考虑区号有两位或三位,三位区号时局地号码为7位或8位

首尾描述符

  • 行首描述符:以“^”符号开头的模式,只能与一行的前缀子串匹配
  • 行尾描述符:以“$”符号结尾的模式只与一行的后缀子串匹配
  • 串首描述符:\A开头的模式只与整个被匹配串的前缀匹配
  • 串尾描述符:\Z结束的模式只与整个被匹配串的后缀匹配

匹配对象(match对象)

match1 = re.search(pattern, string)
if match1:
    ... match1 ... text ... # 使用match对象的处理操作

match对象提供了一组方法,用于检查和使用与匹配有关的信息。

  • 取得被匹配的子串:match.group();通过匹配成功得到match对象,所用的正则表达式自然与目标串里的一个子串成功匹配。通过操作match.group()就能得到这个子串。
  • 在目标串里的匹配位置:match.start();取得match代表的成功匹配在目标串里的实际匹配位置,这是目标串的一个字符位置,即是被匹配子串开始字符的下标。
  • 目标串里被匹配子串的结束位置:match.end()
  • 目标串里被匹配的区间:match.span() == match.start(), match.end()

模式里的组(group)

        在一次成功匹配中,模式串里的各个组也都成功匹配,与它们匹配的那一组字符串将从1开始编号,而后可以通过方法调用match.group(n)获取。作为特殊情况,组0就是与整个模式匹配的字符串。match.groups()将得到一个序对,其中包含从编号1开始的各个组匹配的串。

        组还有一个重要用途,就是在匹配中应用前面的成功匹配,建立前后的部分匹配之间的约束关系。

match = re.search('.((.)e)f', 'abcdef')
print(match .group())    # cdef
print(match .groups())   # ('de', 'd')

你可能感兴趣的:(数据结构与算法--Python,正则表达式,python)