正则表达式

為{幸葍}努か 提交于 2020-01-25 23:40:37

1 正则表达式概述

1.1 什么是正则表达式

正则表达式:Regular Expression,是一些由特殊的字符和符号组成的字符串,主要用来进行高级的文本匹配、搜索、替换等功能操作。
正则表达式是一个独立的技术,python中提供了re模块来支持正则表达式

1.2 第一个正则表达式

import re

target = "hello, email@qq.com regexp in python with regular on expression"

reg = r"l"
print(re.findall(reg, target))

2 正则表达式操作语法

2.1 基本语法

2.1.1 基本正则语法
匹配字符符号 描述 案例
literal 匹配文本字面值 foo
re1/re2 匹配正则表达式 re1或者re2 foo/bar
^ 匹配目标字符串开头位置 ^Dear
$ 匹配目标字符串结束位置 py$
. 匹配任意一个字符(\n 除外) h.llo
? 匹配任意一个字符出现0次/1次 foo?
+ 匹配任意一个字符出现1次/n次 foo+
* 匹配任意一个字符出现0次/n次 foo*
{m} 匹配任意一个字符按 m 次 foo{m}
{m,} 匹配任意一个字符出现至少 m 次 foo{m,}
{m,n} 匹配任意一个字符出现 m~n 次 foo{2,5}
[0-9] 匹配任意一个 0~9 之间的数字 [0-9]{11}
[^0-9] 匹配任意一个非数字字符
[3-6] 匹配任意一个 3~6 之间的数字
[0-10] 匹配 00 或者 10 两个数字
[a-z] 匹配任意一个小写字母
[A-Z] 匹配任意一个大写字母
[a-zA-Z] 匹配任意一个字母
[a-zA-Z0-9_] 匹配任意字母/数字/下划线
(...) 匹配分组正则表达式 (0-9){3}-(0-9){4}

2.1.2 正则表达式:元字符

符号 描述 示例
\d 匹配任意一个[0-9]的数字 data\d+.txt
\D 匹配任意一个非数字字符 info_\D+.log
\s 匹配任意一个空白字符[\n\t\r\v\f] <a\s+href=
\S 匹配任意一个非空白字符 \S{6}
\w 匹配任意一个字母/数字/下划线 \w{8,18}
\W 匹配任意一个非字母/数字/下划线
\b 匹配任意一个单词的边界 \bfood\b
\ 转义字符,可以用于匹配正则中用到的字符 \, ., *, +,...

2.1.3 正则表达式:零宽断言

符号 描述
(?reg) 特殊标记参数
(?:reg) 匹配不用保存的分组
(?Preg) 匹配到分组结果命名 name
(?P=name) 匹配(?Preg)前的文本
(?#comment) 注释
(?=reg) 正向前视断言(零宽断言)
(?!reg) 负向前视断言(零宽断言)
(?<=reg) 正向后视断言(零宽断言)
(?<!reg) 负向后视断言(零宽断言)
(?(id/name)Yre1/Nre2) 条件断言分组

3 正则语法案例

3.1 基本正则语法

"""
FILE    : 正则表达式语法操作
DATETIME: 2018/10/18 11:22
AUTHOR  : chenliang
DESC    : 
"""
import re

s = '''Are you new to Django or to programming? This is the place to start!
From scratch: Overview | Installation
Tutorial: Part 1: Requests and responses | Part 2: Models and the admin site
| Part 3:
Views and templates | Part 4: Forms and generic views | Part 5: Testing |
Part 6:
Static files | Part 7: Customizing the admin site
Advanced Tutorials: How to write reusable apps | Writing your first patch
for Django123_
'''

# 1 基本语法
reg1 = r"to"
print(re.findall(reg1, s))
# ['to', 'to', 'to', 'to', 'to', 'to', 'to']

# 2 或者匹配
reg2 = r"Django|part"
print(re.findall(reg2, s))
# ['Django', 'Django']

# 3 开头匹配
reg3 = r"^Are"
print(re.findall(reg3, s))
# ['Are']

# 4 结尾匹配
reg4 = r"Django123_$"
print(re.findall(reg4, s))
# ['Django123_']

# 5 认识字符匹配
reg5 = r"Ho."
print(re.findall(reg5, s))
# ['How']

# 6 范围匹配?
reg6 = r"pr?"
print(re.findall(reg6, s))
# ['pr', 'p', 'p', 'p', 'p', 'p', 'p']

# 7 范围匹配+
reg7 = r"pr+"
print(re.findall(reg7, s))
# ['pr']

# 8 范围匹配*
reg8 = r"pr*"
print(re.findall(reg8, s))
# ['pr', 'p', 'p', 'p', 'p', 'p', 'p']

# 9 范围匹配{m}
reg9 = r"l{2}"
print(re.findall(reg9, s))
# ['ll']

# 10 范围匹配{m, n}
reg10 = r"l{1,3}"
print(re.findall(reg10, s))
# ['l', 'll', 'l', 'l', 'l', 'l', 'l', 'l']

# 11 范围匹配{0-9}
reg11 = r"[0-9]+"
print(re.findall(reg11, s))
# ['1', '2', '3', '4', '5', '6', '7', '123']

# 12 范围匹配[a-z]
reg12 = r"[a-z]{10}"
print(re.findall(reg12, s))
# ['programmin', 'nstallatio', 'ustomizing']

# 13 范围匹配[a-zA-Z0-9_]
reg13 = r"[a-zA-Z0-9_]{10}"
print(re.findall(reg13, s))
# ['programmin', 'Installati', 'Customizin', 'Django123_']

3.2 元字符语法

"""
FILE    : 元字符语法
DATETIME: 2018/10/19 11:52
AUTHOR  : chenliang
DESC    : 
"""
import re

s = """
Django Community 11445 people, 164 countries, 3854 packages and projects.
"""

# 1 \d
reg1 = r"\d+"
print(re.findall(reg1, s))
# ['11445', '164', '3854']

# 2 \s
reg2 = r"\s+"
print(re.findall(reg2, s))
# ['\n', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '\n']

# 3 \b
reg3 = r"\ban+"
print(re.findall(reg3, s))
# ['an']

# 4 \w
reg4 = r"\w{5}"
print(re.findall(reg4, s))
# ['Djang', 'Commu', '11445', 'peopl', 'count', 'packa', 'proje']

3.3 分组查询语法

"""
FILE    : 分组查询语法
DATETIME: 2018/10/19 11:57
AUTHOR  : chenliang
DESC    : 
"""
import re

s = '''
<img src="./images/1.jpg"/>
<img src="./images/2.jpg"/>
<img src="./images/3.jpg"/>
<img src="./images/4.jpg"/>
<img src="./images/5.jpg"/>
'''

reg = r'<img\s+src="(.*)"/>'

res = re.finditer(reg, s)
for r in res:
    print(r.group())
    print(r.group(1))
"""
result:
    <img src="./images/1.jpg"/>
    ./images/1.jpg
    <img src="./images/2.jpg"/>
    ./images/2.jpg
    <img src="./images/3.jpg"/>
    ./images/3.jpg
    <img src="./images/4.jpg"/>
    ./images/4.jpg
    <img src="./images/5.jpg"/>
    ./images/5.jpg
"""

3.4 零宽断言语法

"""
FILE    : 零宽断言
DATETIME: 2018/10/19 12:01
AUTHOR  : chenliang
DESC    : 
"""
import re

# 目标字符串
s = 'aahelloworldbbhellojerryjerryup'

# 1 正向前视断言
reg1 = r".{2}hello(?=world)"
res = re.finditer(reg1, s)
for r in res:
    print(r.group())  # aahello

# 2 负向前视断言
reg2 = r".{2}hello(?!world)"
res = re.finditer(reg2, s)
for r in res:
    print(r.group())  # bbhello


# 3 正向后视断言
reg3 = r".(?<=hello)jerry.{2}"
res = re.finditer(reg3, s)
for r in res:
    print(r.group())  # ojerryje

# 4 负向后视断言
reg4 = r"(?<!hello)jerry.{2}"
res = re.finditer(reg4, s)
for r in res:
    print(r.group())  # jerryup

贪婪匹配和懒惰匹配

"""
FILE    : 贪婪匹配和懒惰匹配
DATETIME: 2018/10/19 12:10
AUTHOR  : chenliang
DESC    : 
"""
import re
target_str = "<div>hello</div><p>world</p><div>regular expression</div>"
# 正则表达式:贪婪模式
reg = re.compile(r"<div>.*</div>")
# 查询数据
res = reg.search(target_str)
print(res.group())
# <div>hello</div><p>world</p><div>regular expression</div>

# # 正则表达式:非贪婪模式
reg = re.compile(r"<div>.*?</div>")
# 查询数据
res = reg.search(target_str)
print(res.group())
# <div>hello</div>

3 python中的正则

3.1 为什么使用正则表达式

正则表达式本身就是对于字符串的高效处理,尽管字符串本身也内置了一些操作函数,但是相对于较为复杂的需求,通过正则表达式的操作更加的灵活并且效率更高
正则表达式在程序中的主要应用,有以下几个方面
匹配:测试一个字符串是否符合正则表达式语法,返回True或者False
获取:从目标字符串中,提取符合正则表达式语法的字符数据
替换:在目标字符串中查询符合正则语法的字符,并替换成指定的字符串
分割:按照符合正则表达式的语法字符对目标字符串进行分割

3.2 创建正则表达式对象的方式

隐式创建:通过一个普通字符串,直接创建正则表达式;要求:必须通过re模块的函数调用才能正常编译执行

import re

# 创建一个正则表达式
reg = r"\bfoo\b"

# 从目标字符串中提取数据
result = re.findall(reg, target_str)

显式创建:通过内建函数compile()编译创建一个正则表达式对象;要求:可以通过调用该类型的方法,完成字符的操作

import re

target_str = "helloworldhelloregexp"

# 1 函数
reg = r"(?<=hello).{3}"
print(re.findall(reg, target_str))

# 对象
reg2 = re.compile(r"(?=hello).{3}")
print(reg2.findall(target_str))

3.3 常用方法

常用方法 描述
re.findall(s, start, end) 返回(指定位置)查询到结果内容的列表
re.finditer(s, start, end) 返回(指定位置)查询到结果匹配对象的生成器
re.search(s, start, end) 返回(指定位置)第一次查询到的匹配对象
re.match(s, start, end) 返回(指定位置)从第一个字符串匹配到的结果对象
re.sub(s, r, c) 使用r替换字符串中的所有匹配的数据,c是替换次数
re.subn(s, r, c) 使用r替换字符串中所有匹配的数据,c是替换次数
re.split(s, m) 使用正则表达式拆分字符串,m是拆分次数

代码示例

import re

target_str = "helloworldhellojerryhelloregularexpression"

reg = r"hello"

# findall()
print(re.findall(reg, target_str))
# ['hello', 'hello', 'hello']

# finditer()
res = re.finditer(reg, target_str)
for s in res:
    print(s.group())
"""
    hello
    hello
    hello
"""

# search()
res = re.search(reg, target_str)
print(res)
# <re.Match object; span=(0, 5), match='hello'>

# match()
res = re.match(reg, target_str)
print(res)
# <re.Match object; span=(0, 5), match='hello'>

# sub
res = re.sub(reg, "**", target_str)
print(res)
# **world**jerry**regularexpression

# subn
res = re.subn(reg, "**", target_str)
print(res)
# ('**world**jerry**regularexpression', 3)

# split
res = re.split(reg, target_str)
print(res)
# ['', 'world', 'jerry', 'regularexpression']
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!