当前位置: 首页 > news >正文

正则表达式优化建议

文章目录

    • 优化正则表达式
      • 代码示例:
      • 注意事项:
    • 一些常见的正则表达式陷阱

优化正则表达式是提高文本处理效率和准确性的重要步骤。以下是一些优化正则表达式的方法:
以下是整理归纳后的正则表达式优化技巧:

优化正则表达式

一、预编译相关

  1. 预编译正则表达式,在多次使用同一个正则表达式时,可节省重复编译的时间。

二、字符选择相关

  1. 使用具体的字符类而不是通配符.,当知道要匹配的具体字符时,减少匹配范围。
  2. 使用最具体的字符类,例如只匹配数字时使用\d而不是[0-9]
  3. 如果一个字符集只包含一个字符,可以直接使用该字符而不是字符集。
  4. 在字符集中,将更频繁出现的字符放在前面,微优化匹配过程。
  5. 使用字符集(如[a-zA-Z0-9])来匹配一组特定的字符,比使用多个单独的字符类更高效。

三、量词相关

  1. 限制量词的范围,使用{min,max}量词来限制匹配的数量,避免无限制的*+
  2. 使用适当的量词(如{1,}{1,2}{0,1})来精确控制匹配的次数。

四、避免嵌套和贪婪匹配

  1. 避免嵌套量词,嵌套的量词可能会导致性能问题。
  2. 使用非贪婪量词(如*?+???)代替贪婪量词,以减少不必要的回溯。

五、分组相关

  1. 使用非捕获组(?:...),当不需要捕获匹配的文本时,避免不必要的性能开销。
  2. 优化或避免捕获组,捕获组会增加正则表达式的复杂性,可能导致性能下降,尽量减少捕获组的使用,或者只在必要时捕获。
  3. 对于不需要捕获的分组,使用固化分组(?:...),提高效率,正则表达式引擎不需要保存这些分组的捕获结果。

六、锚点和范围限定相关

  1. 使用锚点,使用^$锚点来指定匹配必须发生在字符串的开始或结束,减少不必要的匹配尝试。
  2. 使用明确的锚点,明确指定匹配必须发生在字符串的开始或结束,而不是依赖于默认行为。
  3. 尽可能地限定匹配的范围,例如,使用^$来指定匹配行的开始和结束。

七、其他优化技巧

  1. 避免不必要的模式,不要在正则表达式中包含不必要的模式,如在非必要的地方使用分组。
  2. 避免捕获过多的数据,如果只需要部分数据,避免捕获整个匹配文本,只捕获必要的部分。
  3. 避免不必要的转义字符,尽可能地避免使用不必要的转义字符。
  4. 优化选择分支的顺序,将最可能出现的模式放在选择分支的前面,更快地匹配到正确的模式。
  5. 使用预搜索断言,使用正向前瞻(?=...)和负向前瞻(?!...)来预搜索特定模式,而不实际移动匹配指针。
  6. 考虑使用多行模式,如果正则表达式用于多行文本,使用re.MULTILINE标志,确保^$锚点匹配每一行的开始和结束。
  7. 分析和监控性能,使用正则表达式性能分析工具来监控和优化正则表达式的性能。
  8. 理解正则表达式引擎的实现,了解使用的正则表达式引擎的实现细节,更好地优化表达式。
  9. 避免回溯,设计正则表达式时尽量避免过多的回溯,可通过简化模式或明确指定匹配的顺序来实现。
  10. 使用原子组(?>...)来阻止回溯,一旦匹配了原子组中的内容,就不会再尝试其他可能的匹配。
  11. 简化表达式,尽可能简化正则表达式,去除不必要的分组和选择分支。
  12. 利用预搜索,使用预搜索(?=...)(?!...)来确保匹配或不匹配某个模式,而不消耗字符。
  13. 避免过度使用捕获组,只在需要提取特定子字符串时使用捕获组,过多的捕获组会降低性能。
  14. 测试和调优,使用正则表达式测试工具来测试表达式的性能并进行调优。
  15. 考虑使用其他文本处理方法,如果正则表达式过于复杂或性能不佳,考虑使用其他文本处理方法,如字符串分割、分词或文本分析库。
  16. 考虑使用第三方库,如果正则表达式性能是关键问题,考虑使用专门为性能而优化的第三方库。

代码示例:

示例 1:优化重复的字符集
优化前:

pattern = r"[a-zA-Z0-9][a-zA-Z0-9]"

优化后:

pattern = r"[a-zA-Z0-9]{2}"

解释:
在优化后的表达式中,我们使用 {2} 来指定字符集 [a-zA-Z0-9] 应该重复出现两次,这样就避免了重复书写字符集。

示例 2:避免不必要的捕获组
优化前:

pattern = r"(\d{4})-(\d{2})-(\d{2})"

优化后:

pattern = r"(?:\d{4}-\d{2}-\d{2})"

解释:
如果我们不需要捕获日期的各个部分,可以使用固化分组 (?:...) 来避免不必要的捕获组,这样可以提高匹配效率。

示例 3:使用原子组避免回溯
优化前:

pattern = r"(a*)b"

优化后:

pattern = r"(?>a*)b"

解释:
在优化前的表达式中,a* 是贪婪的,它会尽可能多地匹配 a,然后尝试匹配 b。如果 b 不存在,它会回溯并减少匹配的 a 的数量。使用原子组 (?>...) 后,一旦 a* 匹配成功,就不会再回溯,这可以提高效率。

示例 4:限定匹配范围以减少回溯
优化前:

pattern = r".*a.*b.*"

优化后:

pattern = r".*a.*?b.*"

解释:
在优化前的表达式中,. 是贪婪的,会尽可能多地匹配字符。这可能导致大量的回溯。在优化后的表达式中,我们使用非贪婪量词 .*? 来最小化匹配,从而减少回溯。

示例 5:简化选择分支
优化前:

pattern = r"(abc|ab|a)"

优化后:

pattern = r"a(b(c)?)?"

解释:
在优化前的表达式中,我们使用了多个选择分支来匹配不同的模式。在优化后的表达式中,我们简化了模式,使用嵌套的分组和可选的量词 ? 来实现相同的功能。
通过这些示例,我们可以看到优化正则表达式不仅涉及到改变表达式的结构,还包括减少不必要的复杂性和提高匹配效率。在实际应用中,优化应该基于具体的场景和需求来进行。

注意事项:

  • 优化正则表达式时,不要牺牲表达式的准确性。
  • 测试优化后的正则表达式在不同的数据和场景下是否仍然有效。
  • 对于复杂的正则表达式,考虑将其分解为多个简单的表达式,以提高可读性和可维护性。

一些常见的正则表达式陷阱

一、贪婪与非贪婪匹配的误解

贪婪量词(如*+?)在默认情况下会尽可能多地匹配字符。例如,对于字符串“aaaa”和正则表达式a*,它会匹配整个字符串。但有时候这可能不是预期的结果。非贪婪量词(如*?+???)虽然是为了减少匹配量,但在复杂的表达式中可能会导致意外的行为,因为它们的行为取决于周围的模式和回溯机制。

二、忽略大小写的副作用

当使用忽略大小写的标志时(例如在某些编程语言中通过特定的参数或修饰符),可能会意外地匹配到不希望的字符串。比如,如果你只想匹配特定的大写单词,但由于忽略大小写,小写形式也被匹配了。

三、字符集的意外包含

使用字符集(如[abc])时,如果不仔细考虑字符的范围,可能会意外地包含不需要的字符。例如,[a-z]可能会包含一些特殊字符或标点符号,具体取决于字符编码和语言环境。

四、转义字符的问题

转义字符可能会引起混淆。例如,在正则表达式中,.通常需要转义(如\.)才能匹配一个真正的点字符,而不是作为通配符。如果忘记转义,可能会导致错误的匹配。

五、嵌套量词的复杂性

嵌套量词(如a**)会导致性能问题和难以理解的匹配行为。它们的复杂性使得调试和理解正则表达式变得困难。

六、锚点的误用

锚点(如^$)用于指定匹配在字符串的开始或结束位置。但如果对字符串的结构理解错误,可能会错误地使用锚点,导致不期望的匹配结果。

七、分组的意外捕获

捕获组可能会捕获不需要的文本,或者在不需要捕获的时候进行了捕获,导致性能下降和结果的混乱。

八、忽略多语言和特殊字符

如果正则表达式没有考虑到多语言文本中的特殊字符、变音符号等,可能会在处理不同语言的文本时出现问题。

九、性能陷阱

复杂的正则表达式可能会导致性能下降,尤其是在处理大量文本时。例如,使用过多的分支、嵌套的结构或者无限制的量词可能会使匹配过程变得非常缓慢。

十、边界情况的忽略

有时候,正则表达式可能没有考虑到边界情况,如空字符串、只有一个字符的字符串或者非常长的字符串。这可能会导致意外的行为或错误的匹配结果。

相关文章:

正则表达式优化建议

文章目录 优化正则表达式代码示例:注意事项: 一些常见的正则表达式陷阱 优化正则表达式是提高文本处理效率和准确性的重要步骤。以下是一些优化正则表达式的方法: 以下是整理归纳后的正则表达式优化技巧: 优化正则表达式 一、预…...

Oracle RAC关于多节点访问同一个数据的过程

一、说明 Oracle RAC 存在多个计算节点,但是使用的共享存储。那么多个节点共同访问同一个资源,怎么保证一致性。 白文的逻辑理解简述: 用户1访问rac1 ,通过rac1获取AA数据块后,会加上latch锁。用户2通过rac2访问AA数据…...

IPC$漏洞多位密码爆破方法

虽然不应该将其用于非法的密码破解行为,但从代码修改角度来说,如果要破解多位密码(比如 n 位),你可以按照以下方式调整: 破解多位纯数字密码 如果你想破解 6 位纯数字密码: FOR /L %%i IN (100000,1,999999) DO (net use \\target - ip\ipc$ /user:weak %%i &&…...

计算机网络(八股文)

这里写目录标题 计算机网络一、网络分层模型1. TCP/IP四层架构和OSI七层架构⭐️⭐️⭐️⭐️⭐️2. 为什么网络要分层?⭐️⭐️⭐️3. 各层都有那些协议?⭐️⭐️⭐️⭐️ 二、HTTP【重要】1. http状态码?⭐️⭐️⭐️2. 从输入URL到页面展示…...

Docker打包镜像

Docker打包镜像 前置工作 1.虚拟机中配置好docker环境,并导入nginx,mysql,jdk的镜像 2.下载docker for windows 用idea打包镜像和创建容器需要这个东西支持 下载安装包后执行,无脑回车即可 3.idea中配置docker连接 完成配置后&…...

RabbitMQ 基础架构流程 数据隔离 创建用户

介绍 publisher:消息发送者-exchange:交换机,复制路由的消息-queue:队列,存储消息consumer:消息的消费者 工作流程 publisher消息发送者 -> exchange 交换机 -> queue 队列 -> consumer 消息的消…...

win10系统下openssl证书生成和单向认证

文章目录 前言一、安装openssl二、创建证书目录和必要文件1、创建sslcertTest文件夹2、创建openssl.cnf文件3、创建必要文件 三、创建密钥和证书1、创建根证书私钥ca.key2、创建根证书请求文件ca.csr3、创建自签根证书ca.crt4、创建服务端私钥server.key5、创建服务端证书请求文…...

动态规划的解题思想

1. 从斐波那契数列说起 斐波那契数 (通常用 F(n) 表示)形成的序列称为 斐波那契数列 。该数列由 0 和 1 开始, ,后面的每一项数字都是前面两项数字的和。也就是: F(0) 0, F(2) 1 F(n) F&…...

OpenCV结构分析与形状描述符(10)检测并提取轮廓函数findContours()的使用

操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 在二值图像中查找轮廓。 该函数使用算法 253从二值图像中检索轮廓。轮廓是有用的工具,可用于形状分析和对象检测与识别。参见 OpenC…...

HBase 源码阅读(二)

衔接 在上一篇文章中,HMasterCommandLine类中在startMaster();方法中 // 这里除了启动HMaster之外,还启动一个HRegionServerLocalHBaseCluster cluster new LocalHBaseCluster(conf, mastersCount, regionServersCount,LocalHMaster.class, HRegionSer…...

深度学习每周学习总结N9:transformer复现

🍨 本文为🔗365天深度学习训练营 中的学习记录博客🍖 原作者:K同学啊 | 接辅导、项目定制 目录 多头注意力机制前馈传播位置编码编码层解码层Transformer模型构建使用示例 本文为TR3学习打卡,为了保证记录顺序我这里写…...

数据结构与算法(3)栈和队列

1.前言 哈喽大家好啊,今天博主继续为大家带来数据结构与算法的学习笔记,今天是关于栈和队列,未来博主会将上一章《顺序表与链表》以及本章《栈与队列》做专门的习题应用专题讲解,都会很有内容含量 ,欢迎大家多多支持&…...

11、Django Admin启用对计算字段的过滤

重新定义admin.py中的Hero管理模型如下: admin.register(Hero) class HeroAdmin(admin.ModelAdmin):list_display ("name", "is_immortal", "category", "origin", "is_very_benevolent")list_filter ("…...

xxl-job升级到springboot3.0 导致页面打不开报错)问题

原因:springboot3.0 因为移除了jsp 导致xxl-job不能访问,解决方法如下 1、修改PermissionInterceptor拦截器 package com.xxl.job.admin.controller.interceptor;import com.xxl.job.admin.controller.annotation.PermissionLimit; import com.xxl.job.…...

栈和队列.

目录 1. 栈(Stack) 2. 栈的模拟实现 3. 栈的应用场景 4. 队列(Queue) 5. 队列的模拟实现 6. 循环队列 7. 双端队列(Deque) 8. 面试题 1. 栈(Stack) 栈:一种特殊…...

Parallel.ForEach - 并行处理

Parallel.ForEach 是 C# 中 System.Threading.Tasks.Parallel 类提供的一个方法,用于并行地迭代集合中的每一个元素。Parallel.ForEach 方法允许多个线程同时处理集合中的元素,从而提高程序的执行效率,特别是在处理大量数据或执行耗时任务时。…...

【MySQL】初识MySQL—MySQL是啥,以及如何简单操作???

前言: 🌟🌟本期讲解关于MySQL的简单使用和注意事项,希望能帮到屏幕前的你。 🌈上期博客在这里:http://t.csdnimg.cn/wwaqe 🌈感兴趣的小伙伴看一看小编主页:GGBondlctrl-CSDN博客 目…...

LLM应用实战: 产业治理多标签分类

数据介绍 标签体系 产业治理方面的标签体系共计200个,每个标签共有4个层级,且第3、4层级有标签含义的概括信息。 原始数据 企业官网介绍数据,包括基本介绍、主要产品等 企业专利数据,包括专利名称和专利摘要信息,且专…...

下载Mongodb 4.2.25 版本教程

1、MongoDB 安装包的下载链接 Download MongoDB Community Server | MongoDB 进入如下截图: 2、查找历史版本 往下拉,点击“...”,找到”Archived releases”,点击进入 、 3、下载Mongodb 4.2.25 版本 找到如下图4.2.25版本下载链接,点击就可…...

docker拉取redis5.0.5并建立redis集群

1.配置文件 mkdir -p redis-cluster/7001/ mkdir -p redis-cluster/7002/ mkdir -p redis-cluster/7003/ mkdir -p redis-cluster/7004/ mkdir -p redis-cluster/7005/ mkdir -p redis-cluster/7006/cd redis-clustervim 7001/redis.confbind 0.0.0.0port 7001cluster-enabled…...

基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销,平衡网络负载,延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...

微信小程序 - 手机震动

一、界面 <button type"primary" bindtap"shortVibrate">短震动</button> <button type"primary" bindtap"longVibrate">长震动</button> 二、js逻辑代码 注&#xff1a;文档 https://developers.weixin.qq…...

React19源码系列之 事件插件系统

事件类别 事件类型 定义 文档 Event Event 接口表示在 EventTarget 上出现的事件。 Event - Web API | MDN UIEvent UIEvent 接口表示简单的用户界面事件。 UIEvent - Web API | MDN KeyboardEvent KeyboardEvent 对象描述了用户与键盘的交互。 KeyboardEvent - Web…...

uniapp微信小程序视频实时流+pc端预览方案

方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度​WebSocket图片帧​定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐​RTMP推流​TRTC/即构SDK推流❌ 付费方案 &#xff08;部分有免费额度&#x…...

Redis数据倾斜问题解决

Redis 数据倾斜问题解析与解决方案 什么是 Redis 数据倾斜 Redis 数据倾斜指的是在 Redis 集群中&#xff0c;部分节点存储的数据量或访问量远高于其他节点&#xff0c;导致这些节点负载过高&#xff0c;影响整体性能。 数据倾斜的主要表现 部分节点内存使用率远高于其他节…...

JavaScript基础-API 和 Web API

在学习JavaScript的过程中&#xff0c;理解API&#xff08;应用程序接口&#xff09;和Web API的概念及其应用是非常重要的。这些工具极大地扩展了JavaScript的功能&#xff0c;使得开发者能够创建出功能丰富、交互性强的Web应用程序。本文将深入探讨JavaScript中的API与Web AP…...

搭建DNS域名解析服务器(正向解析资源文件)

正向解析资源文件 1&#xff09;准备工作 服务端及客户端都关闭安全软件 [rootlocalhost ~]# systemctl stop firewalld [rootlocalhost ~]# setenforce 0 2&#xff09;服务端安装软件&#xff1a;bind 1.配置yum源 [rootlocalhost ~]# cat /etc/yum.repos.d/base.repo [Base…...

STM32---外部32.768K晶振(LSE)无法起振问题

晶振是否起振主要就检查两个1、晶振与MCU是否兼容&#xff1b;2、晶振的负载电容是否匹配 目录 一、判断晶振与MCU是否兼容 二、判断负载电容是否匹配 1. 晶振负载电容&#xff08;CL&#xff09;与匹配电容&#xff08;CL1、CL2&#xff09;的关系 2. 如何选择 CL1 和 CL…...

消防一体化安全管控平台:构建消防“一张图”和APP统一管理

在城市的某个角落&#xff0c;一场突如其来的火灾打破了平静。熊熊烈火迅速蔓延&#xff0c;滚滚浓烟弥漫开来&#xff0c;周围群众的生命财产安全受到严重威胁。就在这千钧一发之际&#xff0c;消防救援队伍迅速行动&#xff0c;而豪越科技消防一体化安全管控平台构建的消防“…...

基于江科大stm32屏幕驱动,实现OLED多级菜单(动画效果),结构体链表实现(独创源码)

引言 在嵌入式系统中&#xff0c;用户界面的设计往往直接影响到用户体验。本文将以STM32微控制器和OLED显示屏为例&#xff0c;介绍如何实现一个多级菜单系统。该系统支持用户通过按键导航菜单&#xff0c;执行相应操作&#xff0c;并提供平滑的滚动动画效果。 本文设计了一个…...