python 正则表达式的应用

python 正则表达式

  1. 编程语言和文本编辑器都支持的正则字符(元字符)
  2. python 使用正则表达式
  3. python 使用高级正则表达式
  4. 如何学会正则表达式

在github学习正则表达式

正则字符

  1. 正则是用来处理文本数据的好帮手,大多数程序和文本工具都支持正则,使用起来也非常方便
  2. 在实际应用中,处理爬虫的数据解析,日志的分析处理,以及字符串提取关键数据,应用比较普遍
  3. 在编程中,使用文本编辑器查找或替换关键字,比直接匹配查找更加高效,也更加容易控制。
  4. 点击查看python元字符使用示例

元字符

  • 可以表示数量的元字符
*           0 ,1,2,3,4,5 .....
+           1,2,3,4,5.....
?           0,1
{2}         2        
{0,1}       0,1
{1, }       1,2,3,4,5.....
  • 表示一类字符,通常这些字符能够匹配一个位置,但可以匹配多个种类的字符
[a-z]   可以表示从a-z中的任意一个字符
[^a-z]  可以表示从除了abcde...z以外的字符,例如 123ABCD*&@!等等
.       [*\s]   表示 abcde...zABCDE...Z01234...9 都可以用  .  来表示
\s      [ \n\t\r\f] 表示换行,空格,等空白字符
\w      [a-zA-Z0-9_]   表示 abcde...zABCDE...Z01234...9 都可以用  .  来表示
\d      [0-9]  表示数字,如果想要匹配带小数点,需要使用[\d\.]+ 或者 [0-9\.]+
\S      [^\s]
\D      [^\d]
\W      [^\w]
" "     空格可直接使用
\n      匹配换行
  • 特殊字符(转义字符) \

上面的提到的字符,如果想用这些字符的原来意思,就需要搭配转义字符

1. 需要匹配 "C:\project\cmp" 和 "C:\windows\cmp", 使用下面的正则表达式
	- "C:\\\w+\\cmp"
	- 解释下 "C:\\" 匹配 "C:\"
	- "\w+" 匹配 project 和 windows
	- "\\cmp" 匹配 "\cmp"
2. [] 中表示 - 需要加 \-, 需要匹配 qjn.kjh-123  和 kjojoi-1.23544
	- [\w-\.]+ 报错, 因为这样表示 从 \w 到 \. ,但没有这种说法,所以是错误的
	- [\w\-\.]+ 正确
	- [\w\.-]+ 正确
	- 在[]外面直接使用 - 是没问题的
  • 特殊字符 (开头和结尾判断) ^$ \A\Z
需要获取,abcd 和 aswd, 但是不匹配 aloj和qwed,也就是需要a开头d结尾的四个字符
	- ^a\w{2}d$
	- \Aa\w{2}d\Z
	- 两者是相同的
  • 特殊字符 (或) |
需要获取 ms-windows32 和 windows64
	- (ms-|)windows\d{2}
	- (ms-|)表示 ms- 或者没有
  • 贪婪与非贪婪模式
需要获取 The cat is fat. 中的 cat
使用 The .*at 就会匹配到  cat is fat
使用 The .*?at 就会精确匹配到 cat 

? 表示数量时,是 0 或 1个
跟在数量字符(* +)后面的时候,就是非贪婪模式,意思就是匹配最少的
而贪婪模式相反,意思是匹配最多的字符

以下内容和python一起讲

  • 高级使用 (捕获组(簇))()

    • 非捕获组
    • 普通捕获组
    • 命名捕获组
  • 正则匹配设置

python 使用正则表达式(regular expression)

python 使用正则表达式使用 re

  1. search
  2. findall
  3. match
  4. finditer
  • 四种使用方式都一样,三个参数 func(regex,string,flags)
  • 第一个参数,正则表达式
  • 第二个参数,需要被匹配的字符串
  • 第三个参数,就是正则匹配设置,该参数可选
import re
print(re.findall("C\d+", "abc1234", flags=2))
  1. 第一种是我经常使用的一种了, 介绍下search 方法
原:Hello my dear friend!what's up?
目:dear
import re
string_1 = "Hello my dear friend!what's up?"
target_1 = re.search("dear", string_1)
print(target_1.group())   # dear

# 坑1,无法匹配时,使用group函数获取结果,会报错 NoneType 没有 group 函数
string_1 = "Hello my dear friend!what's up?"
target_1 = re.search("dears", string_1)
print(target_1.group())   # 报错
  1. 第二种在匹配很多相同结构的数据非常有用, 介绍下 findall方法
原: name: 123\nname: 456\nname: 789\nname1: 123
目: name: 123 name: 456 name: 789

import re
string_2 = "name: 123\nname: 456\nname: 789\nname1: 123"
target_2 = re.findall("name: \d+", string_2)
print(target_2) # ["name: 123",  "name: 456", "name: 789"] 三个数据

# 问题,为什么不用search 这种方式,OK,使用search 在匹配一次
import re
string_2 = "name: 123\nname: 456\nname: 789\nname1: 123"
target_2 = re.search("name: \d+", string_2)
print(target_2.group()) # name: 123 一个数据

使用search 只会匹配一次,但 findall 会匹配到所有符合这个表达式的字符串
  1. 第三种方式用的比较少,叫做完全匹配 match
原:123asd456pds
目:123asd456pds

import re
string_3 = "123asd456pds"
target_3 = re.match("\w+", string_3)
print(target_3.group())  # 123asd456pds

此时与search, findall 没什么区别, 换一下原来的字符串
原:?123asd456pds
目:123asd456pds

import re
string_3 = "?123asd456pds"
target_3 = re.match("\w+", string_3)
print(target_3.group())  # 报错,没有匹配到
target_3 = re.search("\w+", string_3)
print(target_3.group())  # 123asd456pds 正常
可以近似地看作 在search的基础上所有匹配都加了 ^$ 判断

python 高级正则表达式

  1. 首先是捕获组,先看一个例子
原:you are the man,you are the best!
目:man 和 best

string_4 = "you are the man,you are the best!"
target_4 = re.findall("you are the (\w+)", string_4)
print(target_4)  # ['man', 'best']

捕获组就是用来精确获取信息的一种方式,因为 you are the 我们是不需要的,但是缺少了,
又没办法匹配到 man 和 best,为了让结果只出现 man 和 best 我们使用捕获组,
结果中就只会有捕获组中的数据了

- 不使用捕获组

string_4 = "you are the man,you are the best!"
target_4 = re.findall("you are the \w+", string_4)
print(target_4)  # ['you are the man', 'you are the best'] 不是我们期望的结果
  1. 非捕获组,使用案例
string_4 = "you are the man,you are the best!"
target_4 = re.findall("you are the (?=\w+)", string_4)
print(target_4)  # ['you are the', 'you are the']

虽然使用了 () , 但是 \w+ 匹配到的数据并没有出现在结果中

原:ms-windows32 和 windows64
目:32 和 64

import re
target = re.findall("(?=ms-|)windows(\d+)", "ms-windows32 和 windows64")
print(target)  # ['32', '64']

ms- 只是用来判断的,如果不加非捕获组,ms- 就会出现在结果中
使用总结  非捕获组通常和(|) 一起使用
  1. 命名捕获组
原:Hello my name is pp.
目:pp

string = "Hello my name is pp."
target = re.search("my name is (?P<name>\w+)", string)
print(target.group("name"))  # pp

# 典型应用,匹配中使用前一个匹配到的数据
原:<html>你好</html>
目:html
string = "<html>你好</html>"
target = re.search("(<(?P<name>\w+)>.*?</(?P=name)>)", string)
print(target.group("name"))  # html

(?P<name>\w+)  命名捕获组
(?P=name) 使用 name 这个命名捕获组捕获到的数据, 两者一致才能正确匹配
该场景在爬虫中使用较多

search 方法中,捕获组的一些常见使用

原:where is your bug?
目:bug

import re
target = re.search("your (\w+)", "where is your bug?")
print(target.group())  #   "where is your bug?"   ? 为什么结果不对
print(target.group(1)) # bug  正确
print(target.groups()) # ('bug',)
target = re.search("your (?P<name>\w+)", "where is your bug?")
print(target.group("name"))  # bug
print(target.groupdict())  # {'name': 'bug'}
  1. 正则匹配设置
    • 忽略大小写
    • 多行修饰
    • . 包含换行符, 即变成所有字符皆可匹配
# 常用情况,忽略大小写
原: abcACBBAC
目: abcACBBAC

target = re.search("[abc]+", "abcACBBAC", flags=2)
print(target.group())   # abcACBBAC 正确匹配
  1. 如何在findall 中使用 捕获组, 使用finditer
import re
string_4 = "abceee abc12312 abc123.qwe"
target_4 = re.finditer("(?P<xxx>abc\w+)", string_4)
data_list = [i for i in target_4]


print([i.group("xxx") for i in data_list])
# ['abceee', 'abc12312', 'abc123']

print([i.groupdict() for i in data_list])
# [{'xxx': 'abceee'}, {'xxx': 'abc12312'}, {'xxx': 'abc123'}]

print([i.groups() for i in data_list])
# [('abceee',), ('abc12312',), ('abc123',)]

print([i.group(1) for i in data_list])
# ['abceee', 'abc12312', 'abc123']

print([i.group() for i in data_list])
# ['abceee', 'abc12312', 'abc123']
  • 注意,finditer 获取到的是迭代器,获取一次后,数据就会清空,需要使用data_list 来保存这一数据

如何学习正则表达式

  1. 在实际的情况下,使用正则表达式去解决问题,多多使用才能快速掌握
  2. 下面是我经常碰到的问题
    1. 不会如何使用,对元字符和函数使用不熟悉
    2. 写错逻辑,写多了也会,真的,因为实在是太长了
    3. 正则表达式写的范围太大,匹配很多错误数据
    4. 正则表达式写的范围太小,错过了很多数据
    5. 正则表达式太复杂,短时间太难看懂,也难以维护
  3. 12 问题,通过多加练习,短时间就能掌握
  4. 34 问题属于两者需要平衡,但我愿意小一点也不愿意匹配到错误数据,但这个还是要视情况而定
  5. 5这个问题,在非常多的正则表达式的情况下,通过人工维护,不仅费时费力,通常是一个难以解决的问题
  6. 不过 5 这个问题,可以另辟蹊径,就是把正则表达式制作成一个通用的工具,增加灵活性,脱离正则表达式的范畴
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值