Python3中正则表达式的使用

正则表达式

正则表达式(regular expression)描述了一种字符串匹配的模式(pattern),可以用来检查一个串是否含有某种子串、将匹配的子串替换或者从某个串中取出符合某个条件的子串等。

首先以一个例子引入:

一个文本文件里面存储了 一些市场职位信息,格式如下所示
Python3 高级开发工程师 上海互教教育科技有限公司上海-浦东新区2/02-18满员
测试开发工程师(C++/python) 上海墨鹍数码科技有限公司上海-浦东新区2.5/每月02-18未满员
Python3 开发工程师 上海德拓信息技术股份有限公司上海-徐汇区1.3/每月02-18剩余11人
测试开发工程师(Python) 赫里普(上海)信息科技有限公司上海-浦东新区1.1/每月02-18剩余5人
Python高级开发工程师 上海行动教育科技股份有限公司上海-闵行区2.8/02-18剩余255人
python开发工程师 上海优似腾软件开发有限公司上海-浦东新区2.5/每月02-18满员

现在,我们需要写一个程序,从这些文本里面抓取 所有职位的薪资。

就是要获取这样的结果
2
2.5
1.3
1.1
2.8
2.5

content = '''
Python3 高级开发工程师 上海互教教育科技有限公司上海-浦东新区2万/月02-18满员
测试开发工程师(C++/python) 上海墨鹍数码科技有限公司上海-浦东新区2.5万/每月02-18未满员
Python3 开发工程师 上海德拓信息技术股份有限公司上海-徐汇区1.3万/每月02-18剩余11人
测试开发工程师(Python) 赫里普(上海)信息科技有限公司上海-浦东新区1.1万/每月02-18剩余5人
Python高级开发工程师 上海行动教育科技股份有限公司上海-闵行区2.8万/月02-18剩余255人
python开发工程师 上海优似腾软件开发有限公司上海-浦东新区2.5万/每月02-18满员
'''

将文本内容按行放入列表

splitlines()默认根据\n \t 来切割。切割后的结果保存在列表中
lines = content.splitlines()
for line in lines:
#find方法查找出的是下标。如果查找的内容不存在 -1
     pos = line.find("万/月")
     if pos < 0:
         pos = line.find("万/每月")
         if pos < 0:
             continue

     #最后一个数字的下标
     idx = pos - 1

     while line[idx].isdigit() or line[idx] == ".":
         idx -= 1

     #开始的下标
     new_pos = idx + 1

     print(line[new_pos:pos])
如果我们使用正则表达式,代码可以这样:

import re
p = re.compile(r'([\d.]+)万/每{0,1}月')    #compile 函数的参数,就是正则表达式字符串。
for one in  p.findall(content):
    #compile对象的 findall 方法返回所有匹配的子串,放在一个列表中。
    print(one)
  

正则表达式 - 教程

菜鸟教程:

https://www.runoob.com/regexp/regexp-tutorial.html

在线验证正则表达式

怎么验证你写的表达式 是否能正确匹配到要搜索的字符串呢?

大家可以访问这个网址: https://regex101.com/

在这里插入图片描述

使用字符表示:
点和星号(. *) 
点(.)匹配除换行符之外的所有单个字符
点后面加一个字符(.天)则会匹配出以天结尾的字符(X天)
   eg:春天,夏天,秋天  正则表达式:.天   匹配的结果就是春天夏天秋天
* 表示匹配前面的子表达式任意次,包括0次。*表示匹配次数,结合点(.)使用
   eg:你好,需要帮忙吗?  我们使用正则表达式:,.* 就会匹配出逗号(,)和逗号后面的所有内容
加号和问号(+ ?)
加号(+) 表示匹配前面的子表达式一次或多次,不包括0次。
eg:
春天,是绿色的
夏天,是红色的
秋天,是黄色的
冬天,是白色的
今天,
使用正则表达式: ,.+
匹配的结果为:
,是绿色的
,是红色的
,是黄色的
,是白色的
最后一行,逗号后面没有其它字符了,+表示至少匹配1次, 所以最后一行没有子串选中。
问号(?)匹配0-1次
eg:
春天,是绿色的
夏天,是红色的
秋天,是黄色的
冬天,是白色的
今天,
使用正则表达式:,.?(逗号,点,问号)
匹配的结果是:
,是
,是
,是
,是
,
最后一行,逗号后面没有其它字符了,但是?表示匹配1次或0次, 所以最后一行也选中了一个逗号字符。
花括号{}匹配指定次数
eg:
红彤彤,绿油油,黑乎乎乎乎,绿油油油油

表达式 油{3} 就表示匹配 连续的 油 字 3次 

表达式 油{3,4} 就表示匹配 连续的 油 字 至少3次,至多 4
 \  ^ $  | ( )
反斜杠 \ 在正则表达式中有多种用途。
表示转义字符
eg:
春天.是绿色的 !!!如果使用正则表达式:.*  ;
此时点是一个元字符我们需要使用转义符来表示,应该写成:.*\. 这里(\.)就是对点的转义
字符描述
\w匹配任意一个文字字符,包括大小写字母、数字、下划线,等价于表达式 [a-zA-Z0-9_]
\W匹配任意一个非文字字符,等价于表达式 [^a-zA-Z0-9_]
\n匹配一个换行符。等价于 \x0a 和 \cJ。
\r匹配一个回车符。等价于 \x0d 和 \cM。
\s匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。注意 Unicode 正则表达式会匹配全角空格符。
\S匹配任何非空白字符。等价于 [^ \f\n\r\t\v]
\d匹配0-9之间任意一个数字字符,等价于表达式 [0-9]
\D匹配任意一个不是0-9之间的数字字符,等价于表达式 [^0-9]
\f匹配一个换页符。等价于 \x0c 和 \cL。
[ ]
方括号-匹配几个字符之一
反斜杠也可以用在方括号里面,比如 [\s,.] 表示匹配 : 任何空白字符, 或者逗号,或者点
eg:

[abc] 可以匹配 a, b, 或者 c 里面的任意一个字符。等价于 [a-c][a-c] 中间的 - 表示一个范围从a 到 c。

[akm.] 匹配 a k m . 里面任意一个字符

这里 . 在括号里面不在表示匹配任意字符了,而就是表示匹配 . 这个字符
如果在方括号中使用 ^ , 表示 非方括号里面的字符集合
[^\d] 表示,选择非数字的字符

起始、结尾位置和单行、多行模式
^表示匹配文本的开头位置。

正则表达式可以设定单行模式和多行模式

如果是单行模式 ,表示匹配整个文本的开头位置。

如果是多行模式 ,表示匹配文本每行的开头位置。

比如,下面的文本中,每行最前面的数字表示水果的编号,最后的数字表示价格

001-苹果价格-60002-橙子价格-70,
003-香蕉价格-80,

如果我们要提取所有的水果编号,用这样的正则表达式 :^\d+

content = '''001-苹果价格-60
002-橙子价格-70
003-香蕉价格-80'''

import re
p = re.compile(r'^\d+', re.M)
for one in  p.findall(content):
    print(one)
    
注意:compile 的第二个参数 re.M ,指明了使用多行模式

运行结果如下
001
002
003

如果,去掉 compile 的第二个参数 re.M, 运行结果如下

#单行模式下,^ 只会匹配整个文本的开头位置。

001
`$` 表示匹配文本的结尾位置。

如果是单行模式,表示匹配整个文本的结尾位置。
如果是多行模式,表示匹配文本每行的结尾位置。
比如,下面的文本中,每行最前面的数字表示水果的编号,最后的数字表示价格

001-苹果价格-60002-橙子价格-70,
003-香蕉价格-80,
如果我们要提取所有的水果编号,用这样的正则表达式 \d+$

content = '''001-苹果价格-60
002-橙子价格-70
003-香蕉价格-80'''

import re
p = re.compile(r'\d+$', re.MULTILINE)
for one in  p.findall(content):
    print(one)

注意:compile 的第二个参数 re.MULTILINE ,指明了使用多行模式

运行结果如下
60
70
80

如果,去掉 compile 的第二个参数 re.MULTILINE, 运行结果如下
80

因为单行模式下,$ 只会匹配整个文本的结束位置。
竖线-匹配两者之一
竖线表示匹配前者或后者 。
eg:
    黑色|色 就会匹配出黑色或者色
括号-组选择
括号称之为正则表达式组选择。 是从正则表达式匹配的内容里面扣取出其中的某些部分
eg:
content = '''苹果,苹果是绿色的
橙子,橙子是橙色的
香蕉,香蕉是黄色的'''

import re
p = re.compile(r'^(.*),', re.MULTILINE)
for one in  p.findall(content):
    print(one)
竖线-匹配两者之一
|线表示匹配前者或后者 。
eg:
    黑色|色 就会匹配出黑色或者色
括号-组选择
括号称之为正则表达式组选择。 是从正则表达式匹配的内容里面扣取出其中的某些部分
eg:
content = '''苹果,苹果是绿色的
橙子,橙子是橙色的
香蕉,香蕉是黄色的'''

import re
p = re.compile(r'^(.*),', re.MULTILINE)
for one in  p.findall(content):
    print(one)
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

patmos

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值