原文链接

## 什么是正则表达式
`正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符、及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑`
## 正则表达式规则
<!--more-->

## 正则表达式注意问题
### 数量词的贪婪模式与非贪婪模式
`正则表达式通常用于在文本中查找匹配的字符串。Python里数量词默认是贪婪的,总是尝试匹配尽可能多的字符;非贪婪的则相反,总是尝试匹配尽可能少的字符。`
例如:正则表达式”ab*”如果用于查找”abbbc”,将找到”abbb”。
而如果使用非贪婪的数量词”ab*?”,将找到”a”。
*表示匹配前一个字符0个或多个,加上?后匹配前一个字符0个或1个,使匹配规则变为非贪婪。

### 转义问题
由于字符串中出现特殊字符要采取转义,采用'\'可以进行转义。如果字符串中出现'\',需要采用'\\'才可以转义为'\',
Python里的原生字符串很好地解决了这个问题,在字符串前加上r,表示原生字符串,不用考虑转义问题。
看下面的例子:

import re
s = 'AB\\-001'
print(s)
s = r'AB\-001'
print(s)

使用原生字符串不用写转义的'\'了。
## 正则表达式的应用举例

`1 可以re模块中的match函数实现基本的匹配`

import re
result = re.match(r'^\d{3}\-\d{3,8}$','010-12345')
print(result)
result2 = re.match(r'^\d{3}\-\d{3,8}$','010 12345')
print(result2)

  

`2 可以实现split切割字符串`

#切串
s1 = 'a b c'
print(s1.split(' ') )
s2 = re.split(r'\s+', s1)
print(s2)
s3 = re.split(r'[\s\:\,]+','a,b c::d e, f')
print(s3)

  

pattern = re.compile(r'\d+')
splitrs = re.split(pattern, 'one1two2three3four45six797five')
if sr:
print(splitrs)

  

`3 对匹配规则进行分组`

m = re.match(r'^(\d{3})-(\d{3,8})$','010-12345')
print(m)
print(m.group(0))
print(m.group(1))
print(m.group(2))
print(m.groups())

  

`4 贪婪匹配和非贪婪匹配`

r1 = re.match(r'^(\d+)(0*)$','102300').groups()
print(r1)
r2 = re.match(r'^(\d+?)(0*)$','102300').groups()
print(r2)

`5 编译生成pattern再匹配`

re_telephone = re.compile(r'^(\d{3})-(\d{3,8})$')
r3 = re_telephone.match('010-12345').groups()
print(r3)
r4 = re_telephone.match('043-12345').groups()
print(r4)

match 的另一种写法是这样的

pattern = re.compile(r'hello')
result1 = re.match(pattern, 'hello')
result2 = re.match(pattern, 'helloo, aaa')
result3 = re.match(pattern, 'helo AAB')
result4 = re.match(pattern, 'helloww') if result1:
print(result1 )
else:
print('failed!!!') if result2:
print(result2.group() )
else:
print('failed!!!') if result3:
print(result3.group() )
else:
print('failed!!!') if result4:
print(result4.group() )
else:
print('failed!!!') 

re.compile返回值包含如下属性和函数:
属性:
`1.string: 匹配时使用的文本。`
`2.re: 匹配时使用的Pattern对象。`
`3.pos: 文本中正则表达式开始搜索的索引。值与Pattern.match()和Pattern.seach()方法的同名参数相同。`
`4.endpos: 文本中正则表达式结束搜索的索引。值与Pattern.match()和Pattern.seach()方法的同名参数相同。`
`5.lastindex: 最后一个被捕获的分组在文本中的索引。如果没有被捕获的分组,将为None。`
`6.lastgroup: 最后一个被捕获的分组的别名。如果这个分组没有别名或者没有被捕获的分组,将为None。`
函数:
`1.group([group1, …]):
获得一个或多个分组截获的字符串;指定多个参数时将以元组形式返回。group1可以使用编号也可以使用别名;编号0代表整个匹配的子串;
不填写参数时,返回group(0);没有截获字符串的组返回None;截获了多次的组返回最后一次截获的子串。`
`2.groups([default]):
以元组形式返回全部分组截获的字符串。相当于调用group(1,2,…last)。default表示没有截获字符串的组以这个值替代,默认为None。`
`3.groupdict([default]):
返回以有别名的组的别名为键、以该组截获的子串为值的字典,没有别名的组不包含在内。default含义同上。`
`4.start([group]):
返回指定的组截获的子串在string中的起始索引(子串第一个字符的索引)。group默认值为0。`
`5.end([group]):
返回指定的组截获的子串在string中的结束索引(子串最后一个字符的索引+1)。group默认值为0。`
`6.span([group]):
返回(start(group), end(group))。`
`7.expand(template):
将匹配到的分组代入template中然后返回。template中可以使用\id或\g、\g引用分组,但不能使用编号0。\id与\g是等价的;
但\10将被认为是第10个分组,如果你想表达\1之后是字符’0’,只能使用\g0。`

下面的例子将上述属性和函数打印出来,读者可以打印看看结果

#匹配:单词+空格+单词+任意字符
m = re.match(r'(\w+) (\w+)(?P<sign>.*)','hello world!') print('m.string is %s' %(m.string) )
print('m.re: %s' %(m.re) )
print('m.pos: %d' %(m.pos))
print('m.endpos: %d' %(m.endpos))
print('m.lastindex: %d' %(m.lastindex))
print('m.lastgroup: %s' %(m.lastgroup))
print('m.groups: ' , m.groups())
print('m.group: ' , m.group())
print('m.group(1,2): ' , m.group(1,2))
print('m.groupdict():', m.groupdict())
print('m.start(2):',m.start(2))
print('m.end(2):',m.end(2))
print('m.span(2):',m.span(2))
print("m.expand(r'\g \g\g'):", m.expand(r'\2 \1\3') )

 除此之外还有其他的几个函数 

`6 re.search(pattern, string[, flags])`
search方法与match方法极其类似,区别在于match()函数只检测re是不是在string的开始位置匹配,search()会扫描整个string查找匹配

import re
pattern = re.compile(r'world')
sr = re.search(pattern, 'hello world!')
if sr:
print(sr.group())

  

`7 re.findall(pattern, string[, flags])`
搜索string,以列表形式返回全部能匹配的子串。

pattern = re.compile(r'\d+')
find = re.findall(pattern, 'one1two2three3four45six797five')
if find:
print(find)

`8 re.finditer(pattern, string[, flags])`
搜索string,返回一个顺序访问每一个匹配结果(Match对象)的迭代器。

pattern = re.compile(r'\d+')
finditer = re.finditer(pattern, 'one1two2three3four45six797five')
if(finditer):
print(finditer)
for m in finditer:
print(m.group())

`9 re.sub(pattern, repl, string[, count])`
使用repl替换string中每一个匹配的子串后返回替换后的字符串,首先根据pattern在string中匹配,找到子串返回列表,然后根据repl规则,
替换列表中的字符串。

pattern = re.compile(r'(\w+) (\w+)')
s = 'i say, hello world'
print(re.sub(pattern,r'\2 \1', s)) def func(m):
return m.group(1).title() + ' '+ m.group(2).title() sub = re.sub(pattern, func, s)
print(sub)

  

`10 re.subn(pattern, repl, string[, count])`
返回 一个tuple,tuple两个元素,第一个为re.sub(pattern, repl, string[, count])的结果,第二个为匹配的子串个数。

pattern = re.compile(r'(\w+) (\w+)')
s = 'i say, hello world'
print(re.subn(pattern,r'\2 \1', s)) def func(m):
return m.group(1).title() + ' '+ m.group(2).title() sub = re.subn(pattern, func, s)
print(sub)

到目前为止正则表达式基本知识介绍完毕,谢谢关注我的公众号

python学习(十四)正则表达式的更多相关文章

  1. Python学习十四:filter()

    Python 中内置了filter()函数用于过滤序列. 使用方法: filter()接收一个函数和一个序列. filter()把传入的函数依次作用于每一个元素,然后依据返回值是True还是False ...

  2. python 基础(十四) 正则表达式

    正则表达式 概念: 正则匹配就是一个模糊的匹配 只要符合我的匹配规则 就会认为是正确的数据(精确的匹配) 1.[] #代表原子表把想要匹配的内容写入原子表中   匹配包含的任意一位字符 [a]     ...

  3. 初学 Python(十四)——生成器

    初学 Python(十四)--生成器 初学 Python,主要整理一些学习到的知识点,这次是生成器. # -*- coding:utf-8 -*- ''''' 生成式的作用: 减少内存占有,不用一次性 ...

  4. Python第十四天 序列化 pickle模块 cPickle模块 JSON模块 API的两种格式

    Python第十四天 序列化  pickle模块  cPickle模块  JSON模块  API的两种格式 目录 Pycharm使用技巧(转载) Python第一天  安装  shell  文件 Py ...

  5. 孤荷凌寒自学python第二十四天python类中隐藏的私有方法探秘

    孤荷凌寒自学python第二十四天python类中隐藏的私有方法探秘 (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) 今天发现了python的类中隐藏着一些特殊的私有方法. 这些私有方法不管我 ...

  6. 孤荷凌寒自学python第十四天python代码的书写规范与条件语句及判断条件式

    孤荷凌寒自学python第十四天python代码的书写规范与条件语句及判断条件式 (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) 在我学习过的所有语言中,对VB系的语言比较喜欢,而对C系和J系 ...

  7. Python第二十四天 binascii模块

    Python第二十四天 binascii模块 binascii用来进行进制和字符串之间的转换 import binascii s = 'abcde' h = binascii.b2a_hex(s) # ...

  8. python学习第四讲,python基础语法之判断语句,循环语句

    目录 python学习第四讲,python基础语法之判断语句,选择语句,循环语句 一丶判断语句 if 1.if 语法 2. if else 语法 3. if 进阶 if elif else 二丶运算符 ...

  9. python学习第四次笔记

    python学习第四次记录 列表list 列表可以存储不同数据类型,而且可以存储大量数据,python的限制是 536870912 个元素,64位python的限制是 1152921504606846 ...

随机推荐

  1. Spark之编程模型RDD

    前言:Spark编程模型两个主要抽象,一个是弹性分布式数据集RDD,它是一种特殊集合,支持多种数据源,可支持并行计算,可缓存:另一个是两种共享变量,支持并行计算的广播变量和累加器. 1.RDD介绍 S ...

  2. Centos6升级至openssh-7.5p1

    最近公司有几台服务器需要搬至甲方(政府单位),所以在安装服务时用的是16年的openssh7.3pl, 今天通知我们有漏洞,需要再一次升级,看到官方文档上版本已升级至7.5,所以干脆直接搞7.5 具体 ...

  3. 与面试官谈笑风生 | Python面向对象之访问控制

    Python从设计之初就是一门面向对象的语言,面向对象思想的第一个要素就是封装.所谓封装,通俗的讲就是类中的属性和方法,分为公有和私有,公有可以被外界访问,私有不能被外界访问,这就是封装中最关键的概念 ...

  4. Java 学习笔记 ------第三章 基础语法

    本章学习目标: 认识类型与变量 学习运算符的基本使用 了解类型转换细节 运用基本流程语法 一.类型(基本类型) 所谓基本类型,就是在使用时,得考虑一下数据用多少内存长度存比较经济,利用程序语法告诉JV ...

  5. 依据Right-BICEP要求的对四则运算2的测试

    代码: #include <iostream> #include <time.h> #include <stdio.h> #include <stdlib.h ...

  6. Java微笔记(8)

    Java 中的包装类 Java 为每个基本数据类型都提供了一个包装类,这样就可以像操作对象那样来操作基本数据类型 基本类型和包装类之间的对应关系: 包装类主要提供了两大类方法: 将本类型和其他基本类型 ...

  7. C语言的知识与能力予以自评

    看到一个问卷不错,拟作为第三次作业的部分内容. 你对自己的未来有什么规划?做了哪些准备?答:多学习几门生存技巧,首先先学会碰壁. 你认为什么是学习?学习有什么用?现在学习动力如何?为什么?答:学习是人 ...

  8. 团队作业4——第一次项目冲刺(Alpha版本)第二次

    一.会议内容 各人进行下一步工作 发现沟通流程问题并解决 二.各人工作 成员 计划任务 遇见难题 贡献比 塗家瑜(组长) 后端逻辑处理 无 1 张新磊 数据库搭建 无 1 姚燕彬 测试计划编写 无 1 ...

  9. WPF和Expression Blend开发实例:充分利用Blend实现一个探照灯的效果

    本篇文章阅读的基础是在读者对于WPF有一定的了解并且有WPF相关的编码经验,对于Blend的界面布局有基础的知识.文章中对于相应的在Blend中的操作进行演示,并不会进行细致到每个属性的介绍.同时,本 ...

  10. freemarker中空值 null的处理 ?exists ?if_exists ?default(“”)

    exists:由空值测试运算符的引入,它被废弃了. exp1?exists 和 exp1??是一样的, ( exp1)?exists 和(exp1)??也是一样的. if_exists:由默认值运算符 ...