让开发人员偷懒的正则表达式

news2024/11/29 7:41:20

正则表达式是一种基于特殊模式符号系统的文本处理系统。简而言之,它为程序员提供了轻松处理和验证字符串的能力。它代表了DRY(Don't Repeat Yourself)原则的实现,在几乎所有支持的语言中,正则表达式模式根本不会改变形式。

在后端和前端应用程序上编写的代码将是相同的,从而为团队实现相同的功能节省了时间。还值得强调的是,该模块非常适合处理大型或复杂的字符串,因此可以简单快速地解决与它们相关的问题。

它发生在厨房里的一杯茶或团队 zoom-call 中,你可以听到正则表达式很难学习、编写和阅读,而且通常它们是由糟糕的人发明的😈。但是吗?让我们弄清楚。

注意:

本文适用于那些认为正则表达式复杂、难以理解的人以及那些认为基本知识完全足以胜任工作的人。

它看起来像什么

以下是用于确定俄罗斯电话号码的 6 种编程语言的示例。

在此示例中,您可以立即注意到 Regex 模块的第一个功能:条件模式将完全相同,您可以轻松地与使用另一种编程语言编写的团队共享您的代码。在不同团队之间快速“摸索”代码库的能力节省了开发和实施功能的时间。

出现的历史

正则表达式最早出现在 20 世纪 50 年代中期关于自动机理论和形式语言理论的科学论文中。Stefan Cole Kleen 被认为是第一个引入正则表达式概念的人。

Ken Thompson 在他的工作中提出的原则和想法得到了实际的实施,并以他轻巧的手融入了 Perl 语言。

根据定义,正则表达式是您的编程语言的一个模块,用于搜索和操作文本。

正则表达式语言不是成熟的编程语言,但与其他语言一样,它有自己的语法和命令。

哪些编程语言支持它们?

列表非常大,这里只是其中的几个:

  • C

  • C#

  • C++

  • Cobol

  • Delphi

  • F#

  • Go

  • Groovy

  • Haskell

  • Java

  • JavaScript

  • Julia

  • Kotlin

  • MATLAB

  • Objective-C

  • PHP

  • Perl

  • Python

  • R

  • Ruby

  • Rust

  • Scala

  • Swift

  • Visual Basic

  • Visual Basic .NET

  • ...

能力

  • 输入数据的模式匹配。

  • 按模板搜索和更改输入数据。

  • 返回输入字符串的第一个或所有结果。

  • 与一般搜索的结果一起返回,搜索时命名而不是子字符串。

  • 通过后替换输入字符串中的字符、单词、词组。

  • 最重要的是,一次编写,随处使用。

它会用在什么地方?

  • 在 IDE 中按模式搜索和替换代码(VS Code、Rider、CLion、VS)

  • 验证字符串以进行模式匹配(文件扩展名)。

  • 验证前面的字段(电子邮件、电话号码和其他)。

  • 验证请求和响应数据。

  • 验证巨大的字符串,然后在不花费大量时间的情况下获取必要的文本片段。

基本语法

^- 字符串开头(意味着输入字符串必须以其后的下一个字符开头。如果您不知道输入字符串的第一个字符,则不适用)。

$- 字符串结尾(意味着此字符之前的所有条件将是输入字符串的最终结果,之后没有任何进一步的结果。如果您想从输入字符串返回多个结果,则不适合)。

*- 表示给定符号之前的先前条件可能会出现一次或多次或根本不会出现(分别可能会重复)。

+- 表示该符号之前的条件必须出现一次或多次(分别可以重复)。

[a-z]- 枚举输入字符串中的有效字符,即它可以是任何小写拉丁字母(a 或 b 或 c ... 或 x 或 y 或 z)。

[0-9]- 枚举输入字符串中的有效字符,即它可以是任何小写拉丁字母(1 或 2 或 3 ... 或 7 或 8 或 9)。

.- 任何单个字符。

\- 选择任何特殊字符。

|– OR 逻辑运算(必须满足此操作数左侧或右侧的条件)

语法简化

\d[0-9]- 从 0 到 9 的任何字符

\D[^0-9]- 除数字以外的任何字符

\w[a-zA-Z0-9_]- 任何拉丁字符、所有数字和“_”

\W[^a-zA-Z0-9_]- 除拉丁字符、数字和“_”之外的任何字符

\s[ ]- 仅限空格

\S[^ ]- 除空格以外的任何字符

基本语法说明

Condition Length

除了验证字符串中的值,我们还可以指定多少个字符应该通过相同的条件。只有三种可能使用长度条件:

{3}– 条件所需的字符数

{3.5}- 最小值。和最大。条件的字符数

{3,}- 强制性最小值。数量和无限最大。数量

注:条件[0-9]可以用缩写代替\d

与小组一起工作(高级)

这会有点棘手,所以做好准备吧。

()- 创建一个匿名组(创建一个子字符串并为其分配内存)

(?‘nameGroup’)- (?<nameGroup>)- 创建命名字符串

(\k<nameGroup>)- 用于从重复代码中删除模式,因此,如果您有一个具有某些条件的命名组“nameGroup”,您不能在模式中写入第二个组,但只需将此指令与一个正则表达式一起使用,该正则表达式仅指示之前描述的组的名称。因此,条件将重复出现,您无需再次描述。

(?:)- 在条件的逻辑括号中选择,不命名和创建子字符串

(<=)- 排除括号内的条件并且不将其包含在选择中。

(?!)- 检查括号内的条件,不将其包括在选择中。

现实生活中的例子

有一次,在工作中,我不得不解析打印在支票上的 QR 码数据,当购买/退回各种商品、服务等时。解析器的第一个版本是在 C# 后端编写的。解析器的代码库大约有 150 行代码,它没有考虑到各种财政登记员(打印支票并将数据发送到联邦税务局的设备)的某些功能。要更改此功能,必须仔细查看、检查每一行代码。后来选项太多了,需要在前端用它来验证。因此,决定使用正则表达式重写它以简化解析器并使其轻松快速地移植到另一种编程语言。

目标:

  • 解析输入值以进行模式验证

  • 获取购买日期和金额的必要字段,以便在系统中进一步使用。

  • 检查字段“n”是否始终等于 1(0 - 退货,1 - 购买)

以下是输入数据的示例:

t=20181125T142800&s=850.12&fn=8715000100011785&i=86841&fp=1440325305&n=1

此类数据解析的正则表达式:

^t=(?<Date>[0-9-:T]+)&s=(?<Sum>[0-9]+(?:\.[0-9]{2})?)&fn=[0-9]+&i=[0-9]+&fp=[0-9]+&n=1$

代码示例 (C#):

private static (string date, string sum) parseQRCode(string data)
{
   var pattern = new Regex(@"^t=(?<Date>[0-9-:T]+)&s=(?<Sum>[0-9]+(?:\.[0-9]{2})?)&fn=[0-9]+&i=[0-9]+&fp=[0-9]+&n=1$", RegexOptions.ECMAScript);
   var matchResult = pattern.Match(data);
   if (!matchResult.Success)
       throw new ArgumentException("Invalid qrCode");
   var dateGroup = matchResult.Groups["Date"];
   if(!dateGroup.Success)
       throw new ArgumentException("Invalid qrCode, Date group not found");
   var sumGroup = matchResult.Groups["Sum"];
   if(!sumGroup.Success)
       throw new ArgumentException("Invalid qrCode, Sum group not found");

   return (dateGroup.Value, sumGroup.Value);
}

代码示例(Typescript):

这个选项是通过Exceptions做的,但是可以通过return false或者return null来做。

const parseQRCode = (data:string) : {date: string, sum: string} => {
  const pattern = new RegExp("^t=(?<Date>[0-9-:T]+)&s=(?<Sum>[0-9]+(?:\.[0-9]{2})?)&fn=[0-9]+&i=[0-9]+&fp=[0-9]+&n=1$");
  const matchResult = pattern.exec(data);
  if (!matchResult)
      throw "Invalid qrCode";
  const dateGroup = matchResult[1];
  if(!dateGroup)
      throw "Invalid qrCode, Date group not found";
  const sumGroup = matchResult[2];
  if(!sumGroup)
      throw "Invalid qrCode, Sum group not found";
  return {date: dateGroup, sum: sumGroup};
};

在输出中,我们得到两个值:

  1. 日期 - 表示购买日期和时间的字段(它只是解析它并将其转换为日期对象)

  1. Sum - 购买金额

现在让我们更详细地分析该模式:

  1. ^- 表示一行的开头

  1. t=(?<Date>[0-9-:T]+)– 所需的字符 t=(以下是任何字符(从 0 到 9 或 - 或 : 或 T)在一个或多个实例中)

  1. &s=(?<Sum>[0-9]+(?:\.[0-9]{2})?)– 必填字符

  1. &s=– 所需的字符序列&和s=

  1. [0-9]+(一个或多个实例中的字符 0 到 9)

  1. (?:\.[0-9]{2})?- 非必需的组从.2 个数字的符号开始

  1. $- 表示行尾

  1. &fn=[0-9]+– 必需的字符&fn=后跟[0-9]+->(在一个或多个实例中是从 0 到 9 的任何数字)

  1. &i=[0-9]+– 必需的字符&i=后跟[0-9]+->(在一个或多个实例中是从 0 到 9 的任何数字)

  1. &fp=[0-9]+– 必需的字符&fp=后跟[0-9]+->(在一个或多个实例中是从 0 到 9 的任何数字)

  1. &n=1– 必填字符&n=1

使用非拉丁字母的问题

当您需要使用整个拉丁字母表时,只需编写[a-zA-Z]. 许多人认为在使用西里尔字母时,编写[а-яА-Я]. 似乎一切都合乎逻辑,一切都很好,但在某些时候你会意识到有时它并不适合你。问题是范围[а-я]不包括字母“ё”,因此,您需要将模式从 更改[а-яА-Я][а-яёА-ЯЁ]以便代码考虑字母表中的特定字母。这个问题不仅存在于西里尔字母中,这个问题也与希腊语、土耳其语、中国和许多其他语言有关。编写应使用这些语言的模式时要小心。

JS 正则表达式标志

  • global (g) - 在找到第一个匹配项后不停止搜索。

  • 多行 (m) - 搜索包含换行符的行(^ 行首,$ 行尾)。

  • insensitive (i) - 不敏感地搜索 (a ≡ A)

  • sticky (y) - 除了匹配之外,搜索还返回子选择匹配开头的索引(IE 不支持)

  • unicode (u) - 搜索包括 unicode 字符(IE 不支持)

  • 单行 (s) - 在此模式下,符号.还包括换行符(Chrome、Opera、Safari 支持)

C#

RegexOptions 中的附加正则表达式设置在 Regex 类的构造函数中公开为附加参数。也可以在 Match、Matches 方法中指定。

  • 无 - 默认设置。

  • IgnoreCase (\i) - 不区分大小写地检查。

  • 多行 (\m) - 使用包含连字符 \n 的行。

  • ExplicitCapture (\n) - 仅将命名组添加到结果中。

  • 已编译(仅在静态版本中有用,加速正则表达式,减慢编译速度)。

  • 单行(.符号将匹配除 \n 之外的任何字符,并在搜索时忽略它)

  • IgnorePatternWhitespace (\x) 。(删除所有空格,构造 []、{} 中的例外)

  • RightToLeft - 从右到左搜索。

  • ECMAScript(类似 JS 的版本,但样式分组与 .NET 中的相同)。

  • CultureInvariant(比较忽略键盘布局)。

良好做法和优化技巧

  1. 分组越少,执行速度越快。如果您不需要它们,请尽量避免使用它们。

  1. 使用缩写(\d,\w和其他)时,请确保它们与您的搜索词完全匹配。最好检查两次。

  1. 如果经常使用正则表达式,全局创建一次,从而减少重复代码量。

  1. 几乎所有地方都可以编译正则表达式,这通常可以优化您的表达式并加快它们的执行速度。但是在验证后使用它们,它会加速你的代码。

  1. 尝试减少特殊符号选择 ( \) 的数量,此功能会降低许多编程语言的执行速度。

  1. 正则表达式支持 UTF 字符代码。在某些时候,这会提高性能,但会降低可读性。如果您决定使用它们,请确保团队会批准您的决定并且这是值得的。

结论

正则表达式只是想看起来很复杂,但实际上,它们提供的功能提供了很多机会,让您可以简化和加快从初级到高级/领导的每个人的工作。

拜托,如果您有任何问题,请随时发表评论,我们可以与您一起讨论。

链接

  • 语言正则表达式基准

  • 在线正则表达式助手,带有所有可用命令的字典并支持多种编程语言

  • 我的 RU 语言原始帖子

PS 不要忘记一条重要规则:“编程很酷。”

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

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

相关文章

【信管7.2】质量保证与质量控制

质量保证与质量控制项目质量管理的两个核心过程就是实施质量保证和控制质量。关于它们两个的区别我们在上一课已经讲了&#xff0c;实施质量保证其实保证的是过程&#xff0c;就是我们的开发过程是不是遵循了质量计划&#xff0c;也就是说&#xff0c;这是保证过程有质量的一个…

视频录制软件有哪些?4款录制视频软件,免费下载

对于不了解录屏的用户&#xff0c;肯定会有这些视频是如何制作出来的疑惑&#xff1f;其实录制视频一件很容易的事情&#xff0c;只需要找到一个可以在录视频的软件就可以了。哪有什么录制视频软件可以录制的呢&#xff1f;下面小编给大家分享4款就可以录制视频的软件&#xff…

ORB-SLAM3算法和代码学习—跟踪恒速运动模型TrackWithMotionModel()

0总述 跟踪运动模型核心思想&#xff1a;假设在极短时间内&#xff0c;相机的运动相同。设相邻时刻的三帧图像分别为k-2帧&#xff0c;k-1帧&#xff0c;k帧&#xff0c;则认为k-2帧到k-1帧相机的运动T_delta1和k-1帧到k帧相机的运动T_delta2相等&#xff0c;如下图所示。当相…

K8S概述及用途

K8S概述 1.K8S说明 K8S(Kubernetes) 是一个可移植的、可扩展的开源平台&#xff0c;用于管理容器化的工作负载和服务&#xff0c;可促进声明式配置和自动化。 Kubernetes 拥有一个庞大且快速增长的生态系统。Kubernetes 的服务、支持和工具广泛可用。 Kubernetes 这个名字源…

海量数据存储面临的问题

海量数据存储面临的问题海量数据存储面临的问题成本高性能低可扩展性差如何实现分布式文件存储如何支撑高效率的计算分析如何解决海量数据存储的问题如何解决海量数据文件查询便捷问题如何解决大文件传输效率慢的问题如何解决硬件故障数据丢失问题如何解决用户查询视角统一规整…

pyhon把程序打包为whl

首先需要一个库&#xff1a;setuptools如果是conda环境的话&#xff0c;这个包是自带的&#xff0c;不需要另外安装。首先把需要打包的py文件放在一个文件夹内&#xff08;我的文件夹名为coordTrans&#xff0c;记住这个名字&#xff0c;后面要用&#xff09;。同时&#xff0c…

dll修复工具下载,dll修复工具注意事项

Dll文件的缺失相信很多人都遇见过吧&#xff0c;只要缺失了一个这样的dll文件&#xff0c;我们的游戏或者软件程序就启动不了了&#xff0c;所以我们就需要去修复它&#xff0c;目前修复有几种方法&#xff0c;最简单的&#xff0c;最适合电脑小白的&#xff0c;那就是dll修复工…

Vue3——第四章(响应式基础:reactive、ref)

一、用reactive()声明响应式状态 我们可以使用 reactive() 函数创建一个响应式对象或数组&#xff1a; 响应式对象其实是 JavaScript Proxy&#xff0c;其行为表现与一般对象相似。不同之处在于 Vue 能够跟踪对响应式对象属性的访问与更改操作。 要在组件模板中使用响应式状…

java后端第六阶段:SpringMVC

1、Spring IoC&#xff08;Inversion of Controller&#xff09;控制反转 使用对象时&#xff0c;由主动new产生对象转换为由外部提供对象&#xff0c;此过程中对象中创建控制权由程序转移到外部&#xff0c;此思想称为控制反转 Spring技术对IoC思想进行了实现 Spring提供了一…

第四十九讲:神州路由器IPv6 OSPFv3和RIPng路由的配置

神州路由器支持IPv6的内部网关路由协议常用的有OPSFv3和RIPng。 实验拓扑图如下所示 配置要求&#xff1a;在两台路由器上启用IPv6 routing&#xff0c; 在接口上配子ipv6协议后&#xff0c;通过配置RIPng和OSPFv3相关命令&#xff0c;观察学习到的路由。 配置步骤&#xff1…

产品试用记录

某产品试用记录 还可以选屏哦

【PWA学习】3. 让你的 WebApp 离线可用

引言 PWA 其中一个令人着迷的能力就是离线(offline)可用 即使在离线状态下&#xff0c;依然可以访问的 PWA离线只是它的一种功能表现而已&#xff0c;具体说来&#xff0c;它可以&#xff1a; 让我们的Web App在无网(offline)情况下可以访问&#xff0c;甚至使用部分功能&#…

Redis哨兵模式搭建

以下配置机器部署ip为 a、b、c&#xff0c;其中a为master节点 需提前创建 /app/user/oms/redis/data 目录 1.1上传 redis-5.0.5.zip 到对应目录&#xff0c;解压 unzip redis-5.0.5.zip # 生成 redis-5.0.5 目录 1.2 修改配置文件 maxclients 10000 #20000 &#xff0…

接口测试实战| GET/POST 请求区别详解

在日常的工作当中&#xff0c;HTTP 请求中使用最多的就是 GET 和 POST 这两种请求方式。深度掌握这两种请求方式的原理以及异同之处&#xff0c;也是之后做接口测试一个重要基础。GET、POST 的区别总结请求行的 method 不同&#xff1b;POST 可以附加 div&#xff0c;可以支持 …

概率论【离散型二维变量与连续性二维变量(下)】--猴博士爱讲课

6.连续型二维变量&#xff08;下&#xff09; 1/7 求边缘分布函数 边缘概率密度 边缘概率密度 2/7 求边缘密度函数 边缘概率密度 3/7 判断连续型二维变量的独立性 F(x,y) Fx(X) * Fy(Y)那么X、Y互相独立 f(x,y) fx(X) * fy(Y)那么X、Y互相独立 这种题目带入验证就可以了 先求…

百度举办首个人机共创大会,最强技术天团邀约全球开发者

1月10日&#xff0c;百度举办Create AI开发者大会&#xff08;下称“Create大会”&#xff09;。作为首个“人机共创大会”&#xff0c;AIGC&#xff08;利用AI技术自动生成内容的生产方式&#xff09;技术被深度应用&#xff0c;创造、搭建、连接了多个科技感爆棚的数字化演讲…

powershell ISE 多个选项卡,替换命令行黑窗口

安装powershell ISE设置权限解决方案1.管理员打开PowerShell2. 执行Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser运行脚本自定义函数&#xff0c;function start_service([string]$Name,$p,$r) {$NewTab $psISE.PowerShellTabs.Add()$NewTab.Displa…

ES之module

模块&#xff1a;一个一个的局部作用域的代码块 模块系统需要解决的主要问题 模块化的问题消除全局变量管理加载顺序 Module的基本用法 模块里面都是局部无法访问 切换幻灯片示例 Base.js // 默认参数 const DEFAULTS {// 初始索引initialIndex: 0,// 切换时是否有动画a…

Repvgg推理时融合BN

Batch Normalization是谷歌研究员于2015年提出的一种归一化方法&#xff0c;其思想非常简单&#xff0c;一句话概括就是&#xff0c;对一个神经元&#xff08;或者一个卷积核&#xff09;的输出减去统计得到的均值&#xff0c;除以标准差&#xff0c;然后乘以一个可学习的系数&…

数字孪生|可视化图表之堆叠面积图

上一篇文章为大家介绍了分组条形图的相关内容&#xff0c;本文介绍的是堆叠面积图。 堆叠面积图是一种特殊的面积图&#xff0c;可以用来比较在一个区间内的多个变量。堆叠面积图和普通的面积图基本一样&#xff0c;唯一的区别就是堆叠面积图每个数据系列的起点都是基于前一个数…