【Python Cookbook】S02E08 编写多行模式的正则表达式

目录

  • 问题
  • 解决方案
  • 讨论

问题

我们打算使用正则表达式对一段文本做匹配,但是希望在进行匹配时能够跨越多行。换句话说,正则表达式中 . 可以匹配任意除了换行符的字符,我们如何让他也能够匹配换行符?

解决方案

例如在如下的两个案例中,text1 为单行内容,text2 内容分在了多行,pattern 为正则化匹配模式。

import repattern = re.compile(r'/\*(.*?)\*/')
text1 = "/* This is a commment */"
text2 = '''/* This is a
multiline comment.*/'''print("text1 result:", pattern.findall(text1))
print("text2 result:", pattern.findall(text2))

结果:

text1 result: [' This is a commment ']
text2 result: []

关于正则化的匹配模式,在这里简述,若读者想要了解更清楚,可以移步博文:【Python Cookbook】S01E24 如何定义正则表达式模式从而准确匹配内容,通过 ? 调整贪心策略为非贪婪

在正则化匹配模式 '/\*(.*?)\*/'

  • /\*:这里有三个字符,分别是 / \ *,其目标是为了匹配字符串中的 /* 内容。而另外的一个字符,反斜杠 \,则是用于转义星号,使其成为普通字符。

  • (.*?):这是一个捕获组。

    • 最基础的圆括号 () 表示捕获匹配的内容
    • . 表示任意字符(除了换行符)
    • ? 表示非贪婪匹配模式,即尽可能少地匹配字符
    • * 表示前一个字符可以出现 0 次或多次。因此,这个捕获组会匹配尽可能少的任意字符,当然除了换行符。
  • \*/:与前面的 /* 类似,匹配字符串中的 */ 符号。同样,反斜杠用于转义星号,使其成为普通字符。

总而言之,上述正则表达式模式用于匹配被 /**/ 包裹的任意文本。但是,不包含换行符。

所以我们应该如何实现换行符也能够匹配呢?通过加入 \n

pattern = re.compile(r'/\*(.*?|.*?\n.*?)\*/')

优化上述模式匹配为:

pattern = re.compile(r'/\*((.|\n)*?)\*/')

正则化匹配模式 /\*((.|\n)*?)\*/ 解释:

前后的内容 /\* \*/ 上述已讲述,不过多赘述,\n 读者应当也熟识,为标准的换行符。

  • ((.|\n)*?) 模式中,各部分含义为:
    • . 还是表示任意除了换行符的字符
    • | 或者的含义,没有加转义字符就是原意
    • (.|\n) 的含义即,“不包含换行符” 或 “换行符”,即,包含换行符的任意字符
    • * 表示前一个字符可以出现 0 次或多次,在这里,(.|\n)* 即可以出现多次任意字符
    • ? 非贪婪模式,结合到整体模式中,即不贪婪的匹配所有在 /* */ 中的,包含换行符的任意字符。

再优化:

pattern = re.compile(r'/\*((?:.|\n)*?)\*/')

新增内容为 ?:,这是什么含义?

  • 在正则化匹配中,?: 是一个非捕获组的标记。其创建一个分组,但不同于普通捕获组,非捕获组不会保存匹配到的文本,也不会影响正则表达式引擎的回溯引用功能。

  • 区别于普通捕获组,其可以避免额外的存储开销,因为它告诉正则表达式引擎不要保存该分组的匹配结果。

讨论

上文我们花了大片篇幅来说明如何使得匹配时候包含换行符,但是其实,re.compile() 函数可接受一个有用的标记,re.DOTALL,这个标识使得正则表达式中的句点 . 可以匹配包含换行符在内的所有符号内容。

import repattern = re.compile(r'/\*(.*?)\*/', re.DOTALL)
text1 = "/* This is a commment */"
text2 = '''/* This is a
multiline comment.*/'''print("text1 result:", pattern.findall(text1))
print("text2 result:", pattern.findall(text2))

结果:

text1 result: [' This is a commment ']
text2 result: [' This is a\nmultiline comment.']

综上所述,对于简单的情况,我们使用 re.DOTALL 标记就可以很好的完成工作。但是如果要处理及其复杂的情况,就需要我们自行定义正则化表达式模式了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/25684.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

React+TS前台项目实战(五)-- 全局常用组件Link封装+使用Omit定义类型

文章目录 前言Link组件1. 功能分析2. 代码注释说明3. 使用方式 总结 前言 接下来的几篇文章,将主要封装全局常用组件,以便于后续编写页面的简易和维护性的提高。本文将主要讲述跳转组件的封装。 Link组件 1. 功能分析 (1)国际化…

java期末细节知识整理(三)

1.一个类是多个对象的共性体现 2.一个类可以有多个修饰符 3.类是将数据和方法封装在一起的一种数据结构 4.类和对象是面向对象程序设计方法中最核心的概念 5.在三目运算符flag?x1:x2中,如果x1和x2中有一个是浮点数,那么返回值…

Vue3父组件如何访问子组件属性和方法

本篇内容主要是父组件如何访问子组件的属性和方法 文章目录 子组件 //son.vue代码const list (info) >{console.log(info) }const name ref("XXXX")//子组件向父组件暴露了一个方法,然后父组件就可以去使用子组件里面的一些属性和方法了 //子组件向…

JAVA Mongodb 深入学习(二)索引的创建和优化

一、常用索引类型 1、单个索引 单个索引的创建 db.你的表名.createIndex({"你的字段名":1}) 单个索引的创建且是唯一索引 db.你的表名.createIndex({"你的字段名":1}),{ unique: true }) 2、复合索引 将多个过滤的字段,做成索引,…

centos使用docker快速安装nginx

1.使用yum install命令安装nginx,如果不是安装最新版,需指定需要安装的版本号 2.随便启动一个nginx 实例,只是为了复制出配置 docker run -p 80:80 --name nginx -d nginx:1.10 3.将容器内的配置文件拷贝到当前目录,别忘了后面的点: docker…

奇安信停服,国内还有什么可用的高防么?

这里写自定义目录标题 背景DDOS怎么办?方案推荐总结 背景 继前段时间百度云加速通知免费服务,6月底奇安信也将停止服务,到时候国内将几乎不存在免费好用的高防CDN了;类似的事情还有阿里云和腾讯云的一年期免费SSl证书也都停止供应…

数字孪生技术之三维建模

近年来,伴随着数字经济的发展,数字孪生技术已经成为推动各行业“数智化”转型的重要手段,并深度运用到工业、城市、基建等智慧化建设中。提到数字孪生,就一定离不开“三维建模”,今天我们就来聊聊三维建模是如何赋能数…

C++:SLT容器-->deque

C:SLT容器-->deque 1. 构造函数2. deque 赋值操作3. deque 大小操作4. deque 插入和删除5. deque 容器数据存取6. deque 排序操作 双端数组&#xff0c;可以对头部和尾部进行插入删除操作 需要导入头文件#include <deque> 1. 构造函数 deque deqT; // 默认构造函数 de…

vue-2 组件传值

组件关系分类 父子关系非父子关系 父子通信流程 父组件通过props将数据传递给子组件 给子组件以添加属性的方式传值子组件内部通过 props 接收模板中直接使用 props 接收的值 父组件 Parent.vue <template><div class"parent" style"border: 3px s…

CST Studio Suite 2020 软件安装教程、安装包下载

CST Studio Suite 2020 安装教程 安装包下载 复制链接在浏览器打开 https://www.qqres.com/3150.html CST Studio Suite 是由Dassault Systmes公司开发的一套电磁场仿真软件。它应用于电子、通信、天线设计、射频与微波、电磁兼容性 (EMC)、电磁干扰 (EMI) 等领域。 CST St…

Unity协程学习心得

前言 个人总结的一些Unity协程学习心得&#xff0c;如有不对请在评论区指出一起学习&#xff01;感谢。 在Unity编程中谈到异步逻辑&#xff0c;可以考虑使用协程来实现。协程&#xff08;Coroutine&#xff09;在Unity中的主要作用就是把一个任务暂停&#xff08;挂起&#…

智慧园区建设方案(Word)

1. 楼栋管理 2. 物业管理 3. 安防管理 4. 门禁管理 5. 停车管理 6. 能源管理 7. 环保管理 8. 园区生活服务 9. 招商管理 10. 收费中心 11. 园区地图 12. 门户网站 软件整套原件获取&#xff1a;本文末个人名片。

使用DPO微调大模型Qwen2详解

简介 基于人类反馈的强化学习 (Reinforcement Learning from Human Feedback&#xff0c;RLHF) 事实上已成为 GPT-4 或 Claude 等 LLM 训练的最后一步&#xff0c;它可以确保语言模型的输出符合人类在闲聊或安全性等方面的期望。但传统的RLHF比较复杂&#xff0c;且还需要奖励…

BabylonJS 6.0文档 Deep Dive 动画(四):通过动画排序制作卡通片

一种最为直接的方法是为每个动画剪辑&#xff08;Animatin Clip&#xff09;指定开始时间&#xff0c;最终形成一个卡通动画&#xff08;Cartoon&#xff09;。 1. 设计 1.1 概述 动画的脚本如下&#xff1a; 摄像机显示了一栋带门的建筑物。摄像机靠近门并停止。门打开&am…

掌控数据流:深入解析 Java Stream 编程

Java 8 引入了一种新的抽象称为流&#xff08;Stream&#xff09;&#xff0c;它可以让你以一种声明的方式处理数据。Java 8 Stream API 可以极大提高 Java 程序员的生产力&#xff0c;使代码更简洁&#xff0c;更易读&#xff0c;并利用多核架构进行外部迭代。这里将详细介绍 …

【NoSQL数据库】Redis简介

Redis Redis简介 Redis关系型数据库和非关系型数据库Redis 简介redis速度快的原因 Redis 配置Linux 源码安装redis命令工具 关系型数据库和非关系型数据库 关系型数据库&#xff08;Relational Database&#xff09;和非关系型数据库&#xff08;Non-Relational Database&…

重学Spring总结

1、Spring框架的诞生 文章目录 1、Spring框架的诞生1、BeanFactory 快速入门1.1、BeanFactory完成了loC思想的实现&#xff1a;1)导入Spring相关的依赖&#xff1a;2)定义Uservice接口及其UserviceImpl实现类&#xff1b;3)创建Bean的配置资源文件&#xff0c;文件名最好为&…

新材料正不断推动模具3D打印行业发展

随着工业4.0的浪潮席卷全球&#xff0c;模具制造行业也迎来了技术革新的新纪元。3D打印技术以其独特的制造优势&#xff0c;正逐渐在模具制造领域崭露头角。然而&#xff0c;要实现模具3D打印技术的广泛应用&#xff0c;高性能的打印材料是不可或缺的关键因素。 材料是模具3D打…

【Golang】Map 稳定有序遍历的实现与探索:保序遍历之道

【Golang】Map 稳定有序遍历的实现与探索&#xff1a;保序遍历之道 大家好 我是寸铁&#x1f44a; 总结了一篇【Golang】Map 稳定有序遍历的实现与探索&#xff1a;保序遍历之道✨ 喜欢的小伙伴可以点点关注 &#x1f49d; 前言&#x1f34e; 在计算机科学中&#xff0c;数据结…

Kylin的基本介绍

一、定义与背景 Kylin是一款开源的分布式分析引擎&#xff0c;主要用于处理OLAP&#xff08;联机分析处理&#xff09;多维查询。它最初由eBay开发并贡献至开源社区&#xff0c;为Hadoop/Spark之上的数据提供SQL查询接口及多维分析&#xff08;OLAP&#xff09;能力&#xff0…