easy-wang

正则表达式匹配的几个步骤:

  1. 用 import re 导入正则表达式模块。
  2.用 re.compile()函数创建一个 Regex 对象(记得使用原始字符串)。
  3.向 Regex 对象的 search()方法传入想查找的字符串。它返回一个 Match 对象。
  4.调用 Match 对象的 group()方法,返回实际匹配文本的字符串。

正则表达式匹配更多模式:

  1. 利用括号分组:group() 和groups() 方法。

>>> phoneNumRegex = re.compile(r\'(\d\d\d)-(\d\d\d-\d\d\d\d)\')
>>> mo = phoneNumRegex.search(\'My number is 415-555-4242.\')
>>> mo.group(1)
\'415
>>> mo.group(2)
\'555-4242\'
>>> mo.group(0)
\'415-555-4242\'
>>> mo.group()
\'415-555-4242\'
>>> mo.groups()
(\'415\', \'555-4242\')
>>> areaCode, mainNumber = mo.groups()
>>> print(areaCode)
415
>>> print(mainNumber)
555-4242
>>> phoneNumRegex = re.compile(r\'(\(\d\d\d\)) (\d\d\d-\d\d\d\d)\')
>>> mo = phoneNumRegex.search(\'My phone number is (415) 555-4242.\')
>>> mo.group(1)
\'(415)\'
>>> mo.group(2)
\'555-4242\'

  2. 用管道匹配多个分组: "|" 第一次出现的匹配文本将作为Match对象返回。

>>> heroRegex = re.compile (r\'Batman|Tina Fey\')
>>> mo1 = heroRegex.search(\'Batman and Tina Fey.\')
>>> mo1.group()
\'Batman\'
>>> mo2 = heroRegex.search(\'Tina Fey and Batman.\')
>>> mo2.group()
\'Tina Fey\'
>>> batRegex = re.compile(r\'Bat(man|mobile|copter|bat)\')
>>> mo = batRegex.search(\'Batmobile lost a wheel\')
>>> mo.group()
\'Batmobile\'
>>> mo.group(1)
\'mobile

  3. 用问号实现可选匹配: "?" 不论这段文本在不在, 正则表达式
    都会认为匹配

>>> batRegex = re.compile(r\'Bat(wo)?man\')
>>> mo1 = batRegex.search(\'The Adventures of Batman\')
>>> mo1.group()
\'Batman\'
>>> mo2 = batRegex.search(\'The Adventures of Batwoman\')
>>> mo2.group()
\'Batwoman\'
>>> phoneRegex = re.compile(r\'(\d\d\d-)?\d\d\d-\d\d\d\d\')
>>> mo1 = phoneRegex.search(\'My number is 415-555-4242\')
>>> mo1.group()
\'415-555-4242\'
>>> mo2 = phoneRegex.search(\'My number is 555-4242\')
>>> mo2.group()
\'555-4242

  4. 用星号匹配零次或多次: "*"( 称为星号)意味着“匹配零次或多次”,即星号之前的分组

>>> batRegex = re.compile(r\'Bat(wo)*man\')
>>> mo1 = batRegex.search(\'The Adventures of Batman\')
>>> mo1.group()
\'Batman\'
>>> mo2 = batRegex.search(\'The Adventures of Batwoman\')
>>> mo2.group()
\'Batwoman\'
>>> mo3 = batRegex.search(\'The Adventures of Batwowowowoman\')
>>> mo3.group()
\'Batwowowowoman

  5.用加号匹配一次或多次: "+"则意味着“ 匹配一次或多次”

>>> batRegex = re.compile(r\'Bat(wo)+man\')
>>> mo1 = batRegex.search(\'The Adventures of Batwoman\')
>>> mo1.group()
\'Batwoman\'
>>> mo2 = batRegex.search(\'The Adventures of Batwowowowoman\')
>>> mo2.group()
\'Batwowowowoman\'
>>> mo3 = batRegex.search(\'The Adventures of Batman\')
>>> mo3 == None
True

  6.用花括号匹配特定次数: "{}"如果想要一个分组重复特定次数,就在正则表达式中该分组的后面,跟上花括
     号包围的数字,除了一个数字,还可以指定一个范围,即在花括号中写下一个最小值、一个逗号和
     一个最大值.

>>> haRegex = re.compile(r\'(Ha){3}\')
>>> mo1 = haRegex.search(\'HaHaHa\')
>>> mo1.group()
\'HaHaHa\'
>>> mo2 = haRegex.search(\'Ha\')
>>> mo2 == None
True

贪心和非贪心匹配:

  Python 的正则表达式默认是“ 贪心” 的,它们会尽
  可能匹配最长的字符串,花括号的“ 非贪心” 版本匹配尽可能最短的字符串,即在
  

>>> greedyHaRegex = re.compile(r\'(Ha){3,5}\')
>>> mo1 = greedyHaRegex.search(\'HaHaHaHaHa\')
>>> mo1.group()
\'HaHaHaHaHa\'
>>> nongreedyHaRegex = re.compile(r\'(Ha){3,5}?\')
>>> mo2 = nongreedyHaRegex.search(\'HaHaHaHaHa\')
>>> mo2.group()
\'HaHaHa\'

 findall() 和search() 方法:

  search()方法: 返回一个 Match对象, 包含被查找字符串中的“ 第一次” 匹配的文本
            

>>> phoneNumRegex = re.compile(r\'\d\d\d-\d\d\d-\d\d\d\d\')
>>> mo = phoneNumRegex.search(\'Cell: 415-555-9999 Work: 212-555-0000\')
>>> mo.group()
\'415-555-9999\'

  findall()方法:返回一组
           字符串, 包含被查找字符串中的所有匹配findall()不是返回一个 Match 对象, 而是返回一个字符串列表,

           只要在正则表达式中没有分组。列表中的每个字符串都是一段被查找的文本, 它匹配该正则表达式。 

>>> phoneNumRegex = re.compile(r\'\d\d\d-\d\d\d-\d\d\d\d\') # has no groups
>>> phoneNumRegex.findall(\'Cell: 415-555-9999 Work: 212-555-0000\')
[\'415-555-9999\', \'212-555-0000\']

      如果在正则表达式中有分组, 那么 findall 将返回元组的列表

>>> phoneNumRegex = re.compile(r\'(\d\d\d)-(\d\d\d)-(\d\d\d\d)\') # has groups
>>> phoneNumRegex.findall(\'Cell: 415-555-9999 Work: 212-555-0000\')
[(\'415\', \'555\', \'1122\'), (\'212\', \'555\', \'0000\')]

字符分类

    缩写字符分类 表示
      \d 0 到 9 的任何数字
      \D 除 0 到 9 的数字以外的任何字符

      \w 任何字母、数字或下划线字符(可以认为是匹配“单词”字符)
      \W 除字母、数字和下划线以外的任何字符
      \s 空格、制表符或换行符(可以认为是匹配“空白”字符)
      \S 除空格、制表符和换行符以外的任何字符

      字符分类[0-5]只匹配数字 0 到 5

>>> xmasRegex = re.compile(r\'\d+\s\w+\')
>>> xmasRegex.findall(\'12 drummers, 11 pipers, 10 lords, 9 ladies, 8 maids, 7
swans, 6 geese, 5 rings, 4 birds, 3 hens, 2 doves, 1 partridge\')
[\'12 drummers\', \'11 pipers\', \'10 lords\', \'9 ladies\', \'8 maids\', \'7 swans\', \'6
geese\', \'5 rings\', \'4 birds\', \'3 hens\', \'2 doves\', \'1 partridge\']

建立自己的字符分类:

  1.字符分类[aeiouAEIOU]将匹配所有元音字符, 不论大小写

>>> vowelRegex = re.compile(r\'[aeiouAEIOU]\')
>>> vowelRegex.findall(\'RoboCop eats baby food. BABY FOOD.\')
[\'o\', \'o\', \'o\', \'e\', \'a\', \'a\', \'o\', \'o\', \'A\', \'O\', \'O\']

  2.也可以使用短横表示字母或数字范围:字符分类[a-zA-Z0-9]将匹配所有小写字母、 大写字母和数字请注意,在方括号内,普通的正则表达式符号不会被解释字符分类将匹配

   数字 0 到 5 和一个句点。你不需要将它写成[0-5.]

  3.过在字符分类的左方括号后加上一个插入字符( ^), 就可以得到“ 非字符类”。
   非字符类将匹配不在这个字符类中的所有字符。

>>> consonantRegex = re.compile(r\'[^aeiouAEIOU]\')
>>> consonantRegex.findall(\'RoboCop eats baby food. BABY FOOD.\')
[\'R\', \'b\', \'c\', \'p\', \' \', \'t\', \'s\', \' \', \'b\', \'b\', \'y\', \' \', \'f\', \'d\', \'.\', \'
\', \'B\', \'B\', \'Y\', \' \', \'F\', \'D\', \'.\']

插入字符和美元字符:

  1.可以在正则表达式的开始处使用插入符号( ^),表明匹配必须发生在被查找文本开始处。

  2.可以再正则表达式的末尾加上美元符号( $),表示该字符串必须以这个正则表达式的模式结束。

>>> beginsWithHello = re.compile(r\'^Hello\')
>>> beginsWithHello.search(\'Hello world!\')
<_sre.SRE_Match object; span=(0, 5), match=\'Hello\'>
>>> beginsWithHello.search(\'He said hello.\') == None
True

>>> endsWithNumber = re.compile(r\'\d$\')
>>> endsWithNumber.search(\'Your number is 42\')
<_sre.SRE_Match object; span=(16, 17), match=\'2\'>
>>> endsWithNumber.search(\'Your number is forty two.\') == None
True

>>> wholeStringIsNum = re.compile(r\'^\d+$\')
>>> wholeStringIsNum.search(\'1234567890\')
<_sre.SRE_Match object; span=(0, 10), match=\'1234567890\'>
>>> wholeStringIsNum.search(\'12345xyz67890\') == None
True
>>> wholeStringIsNum.search(\'12 34567890\') == None
True

通配字符:

  1.在正则表达式中,.(句点)字符称为“通配符”,句点字符只匹配一个字符。

>>> atRegex = re.compile(r\'.at\')
>>> atRegex.findall(\'The cat in the hat sat on the flat mat.\')
[\'cat\', \'hat\', \'sat\', \'lat\', \'mat\']

  2.用点-星匹配所有字符( .*):

>>> nameRegex = re.compile(r\'First Name: (.*) Last Name: (.*)\')
>>> mo = nameRegex.search(\'First Name: Al Last Name: Sweigart\')
>>> mo.group(1)
\'Al\'
>>> mo.group(2)
\'Sweigart\'

  3. 点-星使用“贪心” 模式:它总是匹配尽可能多的文本。要用“非贪心” 模式匹配所有文本, 就使用点-星和问号

>>> nongreedyRegex = re.compile(r\'<.*?>\')
>>> mo = nongreedyRegex.search(\'<To serve man> for dinner.>\')
>>> mo.group()
\'<To serve man>\'
>>> greedyRegex = re.compile(r\'<.*>\')
>>> mo = greedyRegex.search(\'<To serve man> for dinner.>\')
>>> mo.group()
\'<To serve man> for dinner.>\'

   4. 用句点字符匹配换行

    点-星将匹配除换行外的所有字符。通过传入 re.DOTALL 作为 re.compile()的第
    二个参数, 可以让句点字符匹配所有字符, 包括换行字符

>>> noNewlineRegex = re.compile(\'.*\')
>>> noNewlineRegex.search(\'Serve the public trust.\nProtect the innocent.
\nUphold the law.\').group()
\'Serve the public trust.\'
>>> newlineRegex = re.compile(\'.*\', re.DOTALL)
>>> newlineRegex.search(\'Serve the public trust.\nProtect the innocent.\nUphold the law.\').group()
nUphold the law.\').group()
\'Serve the public trust.\nProtect the innocent.\nUphold the law.\'

正则表达式符号总结:

  ?匹配零次或一次前面的分组。
  *匹配零次或多次前面的分组。
  +匹配一次或多次前面的分组。
  {n}匹配 n 次前面的分组。
  {n,}匹配 n 次或更多前面的分组。
  {,m}匹配零次到 m 次前面的分组。
  {n,m}匹配至少 n 次、至多 m 次前面的分组。
  {n,m}?或*?或+?对前面的分组进行非贪心匹配。
  ^spam 意味着字符串必须以 spam 开始。
  spam$意味着字符串必须以 spam 结束。
   .匹配所有字符,换行符除外。
   \d、 \w 和\s 分别匹配数字、单词和空格。
  \D、 \W 和\S 分别匹配出数字、单词和空格外的所有字符。
  [abc]匹配方括号内的任意字符(诸如 a、 b 或 c)。
  [^abc]匹配不在方括号内的任意字符。

不区分大小写的匹配:

  可以向 re.compile()传入 re.IGNORECASE 或 re.I,作为第二个参数。

>>> robocop = re.compile(r\'robocop\', re.I)
>>> robocop.search(\'RoboCop is part man, part machine, all cop.\').group()
\'RoboCop\'
>>> robocop.search(\'ROBOCOP protects the innocent.\').group()
\'ROBOCOP\'
>>> robocop.search(\'Al, why does your programming book talk about robocop so much?\').group()
\'robocop

用sub()方法替换字符串:

  

分类:

技术点:

相关文章: