Python入坑之正则表达式

由于工作需要,最近再一次学习python,很多人看来,我一个写嵌入式C的码农来鼓捣python,估计不是很理解,可能还会有鄙视的。不管怎么说,一切还是工作需要。
目前用已经用C和Java分别开发了几个PC端的命令行程序,作为基础工具,通过它们之间的相互调用来协调完成一些自动化工作,这其中还涉及到很多字符处理,逻辑判断和参数传递问题,这就得再设计一套上层逻辑控制程序来实现业务需求,虽然windows的批处理应该也可以实现,但是被称为“胶水语言”的python风头正火,何不蹭点流量呢?

进入正题, 有字符串如下,我们需要用python提取字符串中的文件路径(不要问我为什么还是这么千篇一律的需求,就是这么简单),实际应用中会有中文路径或者文件名带中文,空格。

"other F:\\cc89.bmp F:\\cc890.bmp other"

直接上正则表达式:

    # 原字符
    test_str = "other F:\\cc89.bmp F:\\cc890.bmp other"

    # match()方法从字符串的第一个字符开始匹配,若第一字符匹配则继续,成功则返回匹配对象,否则返回None
    m = re.match(r'[A-Z]:.+.bmp', test_str)
    if m is not None:
        print(m.group())
    else:
        print("Not match anything")

    # 表达是说明:[A-Z]字符串以A-Z中任意一个字符开始,后面的:一起就构成了盘符如F:, .+任意字符任意次
    # 匹配路径和文件名部分, .bmp就是字面值.bmp,指定文件后缀
    # 此方法运行后并没有成功匹配任何字符串,因为match从字符串第一个字符开始,而
    # search()方法会从头开发搜索整个字符串,直到发现与模式匹配的字串或者字符结束才会停止        

输出结果:

Not match anything

再来:

    m = re.search(r'[A-Z]:.+\.bmp', test_str)
    if m is not None:
        print(m.group())
    else:
        print("Not match anything")
    # 表达式解析:与match样, 不同的是, search从字符串第一个字符开始向后搜索,直到发现匹配项或者字符
    # 结束才会停止

输出:

F:\cc89.bmp F:\cc890.bmp

从无到有,不错,再来:

    # 可以看出match()与search()的还是有区别的
    # 然而search()的输出结果为 F:\cc89.bmp F:\cc890.bmp,也就是两个文件名都被识别出来了,可以仔细分析
    # 一下,表达式的逻辑是没有问题的, 那么问题在于匹配到第一个目标之后,是否需要继续匹配后续的字符
    # 这就涉及到正则表达式的“贪婪”模式,默认情况下.+匹配所有符合的字符, 这就把第一个文件路径全部包含了
    # 以至于两个文件路径被匹配成一个结果。这也没什么问题,但是如果我们只需要第一个文件名呢?
    # 这就需要使用非贪婪模式, 即 .+尽可能少的匹配,而剩余的部分考虑用后面的模式项去处理, 例子中就是\.bmp
    # \.是把.转义为字面值.,构成.bmp文件后缀, 这样当.bmp匹配了之后,由于后面剩余的字符就没有模式去匹配,整个
    # 匹配过程到此结束。 非"贪婪"模式用?来修饰数量词 "*","+","?","{m,n}

    m = re.search(r'[A-Z]:.+?\.bmp', test_str)
    if m is not None:
        print(m.group())
    else:
        print("Not match anything")

输出:

F:\cc89.bmp

嗯嗯,差不多了,再进一步,扩展一下:

    # findall()方法则会从头开始搜索整个字串,把所有匹配的部分都找出来,结果作为list返回
    # 与search()方法类似, 但结束条件不同, search()只会匹配第一个,成功之后即停止,而findall会搜索整个
    # 字符串,所有匹配项都会输出
    m = re.findall(r'[A-Z]:.*?\.bmp', test_str)
    if len(m) > 0:
        print(m)
    else:
        print("Not match anything")

    # 同样,如果findall的模式项变成贪婪版本之后,两个文件名会被一个模式匹配出来
    m = re.findall(r'[A-Z]:.*\.bmp', test_str)
    if len(m) > 0:
        print(m)
    else:
        print("Not match anything")

输出:

['F:\\cc89.bmp', 'F:\\cc890.bmp']
['F:\\cc89.bmp F:\\cc890.bmp']
#说明,findall的输出结果是一个列表,即使是空列表。注意观察上面两个findall的结果,第一个非贪婪版本的list有两个元素,而第二个只有一个元素,两个文件名被一个模式完全匹配出来了。

结果与理论一致,OK核心功能验证完成,准备收工了。

为什么不是C?
其实也尝试过用我的主力语言C来实现,首先sscanf,fscanf,strstr等字符串格式相关函数都用过,不过特别费心费力,开发效率非常低,而且扩展性不好。除了主力语言,作为第二第三语言,Python绝对是一个不错的选择。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值