Python 正则表达式

      • 匹配单字符
      • 匹配变长字符串
      • 范围匹配字符串
      • 匹配边界
      • 匹配分组
      • 正则表达式修饰符 - 可选标志
      • re模块
        • compile
        • match
        • group
        • findall
        • search
        • finditer
        • sub
        • split
        • python贪婪和非贪婪

正则表达式是一个特殊的字符序列,它能帮助你方便的检查一个字符串是否与某种模式匹配

匹配单字符

字符 功能
. 匹配任意1个字符(除了\n)
[ ] 匹配[ ]中列举的字符
\d 匹配数字,即0-9
\D 匹配非数字,即不是数字
\s 匹配空格,即 空格,tab键,换行等
\S 匹配非空格
\w 匹配单词字符,即a-z、A-Z、0-9、_
\W 匹配非单词字符

匹配变长字符串

字符 功能
* 匹配前一个字符出现0次或者无限次,即可有可无
+ 匹配前一个字符出现1次或者无限次,即至少有1次
? 匹配前一个字符出现1次或者0次,即要么有1次,要么没有
{m} 匹配前一个字符出现m次
{m,} 匹配前一个字符至少出现m次
{m,n} 匹配前一个字符出现从m到n次

范围匹配字符串

字符 功能
[0-9a-zA-Z_] 可以匹配一个数字、字母或者下划线
[0-9a-zA-Z_]+ 可以匹配至少由一个数字、字母或者下划线组成的字符串,比如’a100’,’0_Z’,’Py3000’等等
[a-zA-Z_][0-9a-zA-Z_]* 可以匹配由字母或下划线开头,后接任意个由一个数字、字母或者下划线组成的字符串,也就是Python合法的变量
[a-zA-Z_][0-9a-zA-Z_]{0,19} 更精确地限制了变量的长度是1-20个字符(前面1个字符+后面最多19个字符)。

A|B可以匹配A或B,所以(P|p)ython可以匹配’Python’或者’python’。

^表示行的开头,^\d表示必须以数字开头。

\d 表 示 行 的 结 束 , \d 表示必须以数字结束。

匹配边界

字符 功能
^ 匹配字符串开头
$ 匹配字符串结尾
\b 匹配一个单词的边界
\B 匹配非单词边界

匹配分组

字符 功能
| 匹配左右任意一个表达式
(ab) 将括号中字符作为一个分组
\num 引用分组num匹配到的字符串
(?P) 分组起别名
(?P=name) 引用别名为name分组匹配到的字符串

正则表达式修饰符 - 可选标志

正则表达式可以包含一些可选标志修饰符来控制匹配的模式。修饰符被指定为一个可选的标志。多个标志可以通过按位 OR(|) 它们来指定。如 re.I | re.M 被设置成 I 和 M 标志:

修饰符 描述
re.S 使 . 匹配包括换行在内的所有字符
re.I 使匹配对大小写不敏感
re.L 做本地化识别(locale-aware)匹配
re.M 多行匹配,影响 ^ 和 $
re.U 根据Unicode字符集解析字符。这个标志影响 \w, \W, \b, \B.
re.X 该标志通过给予你更灵活的格式以便你将正则表达式写得更易于理解。

re模块

建议使用Python的r前缀

s = 'ABC\\-001' # Python的字符串
# 对应的正则表达式字符串变成:
# 'ABC\-001'

# 使用Python的r前缀,就不用考虑转义的问题了
s = r'ABC\-001' # Python的字符串
# 对应的正则表达式字符串不变:
# 'ABC\-001'

compile

当我们在Python中使用正则表达式时,re模块内部会干两件事情:

  1. 编译正则表达式,如果正则表达式的字符串本身不合法,会报错;
  2. 用编译后的正则表达式去匹配字符串。

如果一个正则表达式要重复使用几千次,出于效率的考虑,我们可以预编译该正则表达式,接下来重复使用时就不需要编译这个步骤了,直接匹配:

import re

# 编译
re_telephone = re.compile(r'^(\d{3})-(\d{3,8})$')
# 使用
ret = re_telephone.match('010-12345').groups()
print(ret) # ('010', '12345')

match

从字符串的起始位置匹配一个模式,如果不是起始位置匹配成功的话,match()就返回none。

# 验证0-100
a = '90'
result = re.match(r'[1-9]\d?$|0$|100$', a).group()
print(result) # 90

group

分组,group()和group(0):表示原字符串; group(1):表示第一组

import re

x = '[email protected]'
ret = re.match(r'(\w+)@(163|126|qq)\.(com|cn|net)$', x)
g1 = ret.groups()
print(g1)  # ('xxxx', 'qq', 'com')

# 验证标签
ret = re.match(r"<(\w*)><(\w*)>.*", "

www.baidu.cn

"
) print(ret.group()) #

www.baidu.cn

# 验证Html s = '

hello python

'
r = re.match(r'<(?P.+)><(?P.+)>.+', s) print(r.group()) #

hello python

findall

在字符串中找到正则表达式所匹配的所有子串,并返回一个列表,如果没有找到匹配的,则返回空列表。

s = 'python=10,java=100,html=55'
r = re.findall(r'\d+', s)
print(r) # ['10', '100', '55']

匹配整个字符串并返回第一个成功的匹配。

import re

s = 'python=10,java=100,html=55'
p = re.search(r'\d+', s)
if p:
    print(p.group())  # 匹配结果:10
    print(p.start())  # 开始索引:7
    print(p.end())  # 结束索引:9
    print(p.span())  # 区间范围:(7,9)

finditer

返回迭代器

import re

s = 'python=10,java=100,html=55'
p_iter = re.finditer(r'\d+', s)
print(type(p_iter))
for item in p_iter:
    print(item.group())

输出信息:

<class 'callable_iterator'>
10
100
55

sub

替换操作

import re

s = 'python=10,java=100,html=55'
result = re.sub('\d+', '##', s)
print(result)  # python=##,java=##,html=##

取出网页标签

s = '\n        岗位职责:\n完成推荐算法、数据统计、接口、后良好的自我驱动力和职业素养,工作积极主动、结果导向\n \n技术要对象分析和设计,了解设计模式\n2、掌握HTTP协议,熟悉MVC、MVVM等概念计,掌握 SQL,熟练使用 MySQL/PostgreSQL 中的一种\n4、掌握NoSQL、M、熟悉 Javascript/CSS/HTML5,JQuery、React、Vue.js\n \n加分项理统计,机器学习,sklearn,高性能,大并发。\n\n        '
r = re.sub(r'', '', s)
print(r)

输出信息:


        岗位职责:
完成推荐算法、数据统计、接口、后良好的自我驱动力和职业素养,工作积极主动、结果导向
 ;
技术要对象分析和设计,了解设计模式
2、掌握HTTP协议,熟悉MVC、MVVM等概念计,掌握 SQL,熟练使用 MySQL/PostgreSQL 中的一种
4、掌握NoSQL、M、熟悉 Javascript/CSS/HTML5,JQuery、React、Vue.js
 ;
加分项理统计,机器学习,sklearn,高性能,大并发。

split

切割操作

import re

s = 'info:xiaoZhang 33 shandong'
r = re.split(r':|\s', s)
print(r)  # ['info', 'xiaoZhang', '33', 'shandong']

python贪婪和非贪婪

Python里数量词默认是贪婪的(在少数语言里也可能是默认非贪婪),总是尝试匹配尽可能多的字符;

非贪婪则相反,总是尝试匹配尽可能少的字符。

在”*”,”?”,”+”,”{m,n}”后面加上?,使贪婪变成非贪婪。

import re

s = "http://www.interoem.com/xxxxx/messageinfo.asp?id=35"
r1 = re.sub(r'(http://.+/).*', lambda x: x.group(1), s)
print(r1)  # http://www.interoem.com/xxxxx/

# 解决贪婪
r2 = re.sub(r'(http://.+?/).*', lambda x: x.group(1), s)
print(r2)  # http://www.interoem.com/

获取图片jpg

import re

s = """"""

r = re.search(r'https.+?\.jpg', s).group()
print(r)

查找单词

s = "hello world ha ha"
r = re.findall(r'\b[a-zA-Z]+\b', s)
print(r) # ['hello', 'world', 'ha', 'ha']

你可能感兴趣的:(Python)