python----正则表达式

哈喽,小伙伴们~
好久不见呀,今天我们来学习一下python中的正则表达式模块,正则表达式在其他语言同样可以使用,不过我们今天只看python中的正则表达式用法。

在使用之前,我们首先了解一下正则表达式。

正则表达式是一种非常高效的字符串匹配算法,其专门用于在复杂字符串中匹配特定字符。也许我们之前听过或没听过正则表达式,不过我认为如果想让你的工作效率提高,那么正则表达式是一定要掌握的!

正则表达式元字符

符号含义
*以前一个字符为依据,重复0次或多次
.匹配任意字符,除了换行符
?以前一个字符为依据,出现0次或1次
+以前一个字符为依据,出现1次或多次
{m}匹配前面字符的m次
{m,}匹配前面字符至少m次
{m,n}匹配前面字符,至少m次,至多n次
[]中括号内是一个字符集合,表示匹配集合内的任意一个符号
0-9a-zA-Z表示匹配0-9,a-z ,A-Z 的所有字符
^如果不是在集合中,则必须在元素开头,表示匹配该符号后的那个元素开头的字符
[^]在集合中,表示匹配除集合元素外的所有字符
$放在最后,表示匹配以其前一个字符结尾的字符串

正则表达式特殊字符

字符含义
\d表示匹配一个数字
\d{5}表示匹配5个数字
\w表示匹配一个字符:匹配a-z,A-Z,0-9,_(4部分)
\w{3}表示匹配3个字符
\s表示匹配空格
\D,\W,\S均表示匹配其小写字符含义的相反字符
\D例如,该特殊字符表示匹配非数字的字符

知道了上面的一些信息,下面我们在python中进行实践练习。
注意:以上所有字符,基本上都可以组合使用,来匹配一些复杂的字符

在python应用正则表达式,我们需要导入re模块,来使用正则表达式

实践一:替换一串字符中的非法字符
在进行创建文件时,文件的名字不能出现以下字符【’\ /😗?",<>|’】,因此当我们从网上爬取到文章保存为文献时,就需要将这些非法字符替换掉,否则创建文件就会发生异常。

我们首先来看一下代码,依据代码进行分析讲解

import re

title = 'fgadfadsga;afd/adf\afds|ad||afd"dfad:asdf*?afd<fdsaf>fdsa,fa"'
# 过滤不合法的字符\ /:*?",<>|
def filter_illegal_character(title):
    title = title.replace('"', '')
    chararter = re.compile(r'[\/:*?,;<>|]', re.I)
    chararter = chararter.findall(title)
    for ch in chararter:
        title = title.replace(ch, '-')

    return title

title = filter_illegal_character(title)
print(title)
首先,代码的第一行导入了正则表达式re模块
接着第二行,是准备的一个字符串,将该字符串中的非法字符过滤掉
紧接着下面3-9行,就是过滤非法字符的函数
然后就是调用上面的函数,并用`title`来接收处理过的字符串返回值
最后一行就是打印该处理后的字符串

在进行处理非法字符时,我们可以自己规定想要将非法字符替换为何种合法字符,我这里是将引号替换为空,其余非法字符用‘-’代替。

观察初始时的title字符串,我们发现里面存在非法字符,下面我们通过正则表达式对非法字符进行替换。

正则表达式分析
由于一个"可以直接进行取代,所以不需要进行正则表达式编写了,我们看下其余的非法字符。
除了"外,其余的非法字符还有\ /:*?,<>|这几个,如果我们想把这几个字符替换掉,我们可以思考一下。对于正则表达式的集合[],他的含义为[]匹配集合内的任意一个元素,而非法字符只要出现在文件名中就不合法,因此我们可以很自然的写出正则表达式[\ /:*?,<>|],该正则表达式的含义就是匹配\ /:*?,<>|中的任意一个字符。

写完了正则表达式,我们看一下如何在python中使用。
要在python中使用,我们可以分为两步:

  • 第一步就是编写处正则表达式,然后调用re.compail函数来定义正则表达式
  • 第二步就是依据第一步定义的规则去查找特定字符串,调用X.findall(title)

X表示第一步定义的正则表达式返回对象
之后就会将匹配到的字符返回为一个列表,上述代码执行匹配结果如下:

在这里插入图片描述
可见,如果正则表达式匹配成功会返回一个列表。

上面是一个非常简单的正则表达式用法,下面我们再看一个稍微复杂的正则表达式用法,该用法为从一串字符串中提取指定字符串

实践二:提取特定字符串
注:测试中准备的字符串为从pubmed上(一个论文下载网站)搜索的文献信息导出的csv文件中读取的一行,下面就将该行中的PMID,TITLE,YEAR,DOI分别提取出来

同样,我们先来看下代码

import re

def extracter_character(line):
    line = line.replace('\n', '')
    # 正则表达式匹配 PMID
    PMID = re.compile('(\d{8}).*', re.I)
    match_PMID = PMID.findall(line)
    # 正则表达式匹配 TITLE
    TITLE = re.compile('\d{8},(.*),\d{4},.*', re.I)
    match_TITLE = TITLE.findall(line)
    # 正则表达式匹配 YEAR
    YEAR = re.compile('\d{8},.*,(\d{4}),{0,1}10\..*', re.I)
    match_YEAR = YEAR.findall(line)
    # 正则表达式匹配 DOI
    DOI = re.compile('\d{8},.*,\d{4},(10\..*)', re.I)
    match_DOI = DOI.findall(line)

    print('PMID:', match_PMID)
    print('TITLE:', match_TITLE)
    print('YEAR:', match_YEAR)
    print('DOI:', match_DOI)

if __name__ == '__main__':
    line = '34520356,Applications of Capacitive Micromachined Ultrasonic Transducers: A Comprehensive Review,2022,10.1109/TUFFC.2021.3112917\n'
    extracter_character(line)

对于使用一个正则表达式来提取特定字符串,那么我们肯定要观察字符串的信息,定义匹配规则,才能较好的匹配字符串。因为这里只列出了一个字符串进行测试,故看不出来什么规则,下面我把导出的csv文件截图一部分,一起观察一下规则:
在这里插入图片描述对比这些文献信息,我们应该就很容易看出一些规则:

  • 对于提取PMID
    我们发现这里的PMID都是8位数字,然后其后面跟着的都是一些其他字符。
    注意:这里有两个重要信息,一是前面几个都是数字,二是数字有八位。由于\d表示匹配一位数字,故\d{8}就表示匹配8位数字。由于前面的8位提取完成了,而后面还有标题,年份,DOI等信息,对于这些信息,我们此时不是太关心,故可以通过.来进行匹配。.表示任意字符(除换行符),而表示其前一个字符出现0次或多次。因此,可以将该字符匹配完全。

  • 对于提取TITLE
    提取TITLE稍微复杂点,首先,对于csv文件我们应该明确一点,csv各列是通过逗号(,)来分隔的 ,这里显示时隐藏了,故我们考虑匹配规则时需要把这个逗号(,)考虑进去。

我们观察提取TITLE,有这样几个信息:TITLE紧跟在PMID后面,并且TITLE的尾部紧跟的是年份,年份也是数字,并且是4位,故我们可以先这样写 \d{8}.*\d{4}.*,这样能表示匹配前面8位数字,中间任意字符,后面再跟4位数字,然后又是0次或多次的任意字符。然而这样还有点问题,就比如字符串:34520356,Applications of Capacitive Micromachined Ultrasonic Transducers: A Comprehensive Review,2022,10.1109/TUFFC.2021.3112917,此时中间的.*匹配出来的结果为(,Applications of Capacitive Micromachined Ultrasonic Transducers: A Comprehensive Review,2022,10.1109/TUFFC.2021.311),因为\d{4}.*意思为只要最后四位是数字就行了,此时即.*匹配了零个字符,因此我们需要调整一下,\d{8},.*\d{4},10.*这样便可匹配成功。注意每列是以逗号(,)隔开,因此匹配时别忘了加上逗号(,)。

  • 对于提取YEAR
    上面写完了,其实YEAR就写好了,就是上面的\d{4},
  • 对于提取DOI
    同样DOI也写完了,就是最后的10.*。不过在这里我们需要注意一下,由于DOI里有.这个字符,而.又是正则表达式的元字符,故我们需要转义为如下形式
    10\..*

上面对于提取的各特定字符,多少有点小问题,不过基本上就是这样。下面我们可以直接看代码里的匹配了。对于代码中正则表达式:
匹配PMID时,如下

PMID = re.compile('(\d{8}).*', re.I)
match_PMID = PMID.findall(line)

我们可见,在\d{8}上,加了括号把该匹配的字符括了起来,加括号的意思就是我们在返回匹配的字符串时,只返回括号内匹配的字符串。而\d{8}就表示匹配的PMID,故提取PMID就需要把该部分括起来。后面同理,需要把以下几部分括起来:
匹配TITLE

TITLE = re.compile('\d{8},(.*),\d{4},.*', re.I)
match_TITLE = TITLE.findall(line)

匹配YEAR

YEAR = re.compile('\d{8},.*,(\d{4}),{0,1}10\..*', re.I)
match_YEAR = YEAR.findall(line)

匹配DOI

DOI = re.compile('\d{8},.*,\d{4},(10\..*)', re.I)
match_DOI = DOI.findall(line)

或许我们都发现了最后还有个参数re.I,这个参数可以先不管,这里无用,re.I意思为忽略字符的大小写,放这里只是让大家知道有这个参数。

下面我们看下匹配结果
在这里插入图片描述
好啦,正则表达式就先写到这里,文章写的有些仓促,后面再继续完善,如果伙伴们决定有帮助,请三连支持呀~~~

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Bug.Remove()

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

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

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

打赏作者

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

抵扣说明:

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

余额充值