【文本处理】正则表达式

一、简介

正则表达式,又称规则表达式,(Regular Expression,在代码中常简写为regex、regexp或RE),是一种文本模式,包括普通字符(例如,a 到 z 之间的字母)和特殊字符(称为"元字符"),是计算机科学的一个概念。正则表达式使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串,通常被用来检索、替换那些符合某个模式(规则)的文本。

二、起源

正则表达式的“鼻祖”或许可一直追溯到科学家对人类神经系统工作原理的早期研究。美国新泽西州的Warren McCulloch和出生在美国底特律的Walter Pitts这两位神经生理方面的科学家,研究出了一种用数学方式来描述神经网络的新方法,他们创造性地将神经系统中的神经元描述成了小而简单的自动控制元,从而作出了一项伟大的工作革新。

在1951 年,一位名叫Stephen Kleene的数学科学家,他在Warren McCulloch和Walter Pitts早期工作的基础之上,发表了一篇题目是《神经网事件的表示法》的论文,利用称之为正则集合的数学符号来描述此模型,引入了正则表达式的概念。正则表达式被作为用来描述其称之为“正则集的代数”的一种表达式,因而采用了“正则表达式”这个术语。

之后一段时间,人们发现可以将这一工作成果应用于其他方面。1968年,Unix之父Ken Thompson就把这一成果应用于计算搜索算法的一些早期研究。Ken Thompson将此符号系统引入编辑器QED,然后是Unix上的编辑器ed,并最终引入grep。Jeffrey Friedl 在其著作《Mastering Regular Expressions (2nd edition)》(中文版译作:精通正则表达式,已出到第三版)中对此作了进一步阐述讲解。

自此以后,正则表达式被广泛地应用到各种UNIX或类似于UNIX的工具中,如大家熟知的Perl。Perl的正则表达式源自于Henry Spencer编写的regex,之后已演化成了pcre(Perl兼容正则表达式Perl Compatible Regular Expressions),pcre是一个由Philip Hazel开发的、为很多现代工具所使用的库。正则表达式的第一个实用应用程序即为Unix中的 qed 编辑器。

三、引擎

正则引擎主要可以分为两大类:一种是确定型有穷自动机(Deterministic finite automaton, DFA),一种是非确定型有穷自动机(Non-deterministic finite automaton,NFA)。这两种引擎都有了很久的历史,当中也由这两种引擎产生了很多变体。于是POSIX的出台规避了不必要变体的继续产生。这样一来,主流的正则引擎又分为3类:一、DFA,二、传统型NFA,三、POSIX NFA。

   - **DFA引擎**:

DFA引擎对每一个字符只进行一次判断。它比较快速且其性能不受正则表达式复杂度的影响,但它不支持某些高级匹配特性,例如捕获组和回溯引用。
DFA 引擎在线性时状态下执行,因为它们不要求回溯(并因此它们永远不测试相同的字符两次)。DFA 引擎还可以确保匹配最长的可能的字符串。但是,因为 DFA 引擎只包含有限的状态,所以它不能匹配具有反向引用的模式;并且因为它不构造显示扩展,所以它不可以捕获子表达式。

   - **NFA引擎**:

NFA引擎可以进行回溯,支持更复杂的正则功能,如前述的捕获组、非贪婪量词以及前后断言等。大部分现代编程语言使用这种引擎。然而,当正则表达式特别复杂时,NFA引擎可能导致性能下降,因为它会尝试所有可能的路径来匹配一个字符串。

传统的 NFA 引擎运行所谓的“贪婪的”匹配回溯算法,以指定顺序测试正则表达式的所有可能的扩展并接受第一个匹配项。因为传统的 NFA 构造正则表达式的特定扩展以获得成功的匹配,所以它可以捕获子表达式匹配和匹配的反向引用。但是,因为传统的 NFA 回溯,所以它可以访问完全相同的状态多次(如果通过不同的路径到达该状态)。因此,在最坏情况下,它的执行速度可能非常慢。因为传统的 NFA 接受它找到的第一个匹配,所以它还可能会导致其他(可能更长)匹配未被发现。

POSIX NFA 引擎与传统的 NFA 引擎类似,不同的一点在于:在它们可以确保已找到了可能的最长的匹配之前,它们将继续回溯。因此,POSIX NFA 引擎的速度慢于传统的 NFA 引擎;并且在使用 POSIX NFA 时,您恐怕不会愿意在更改回溯搜索的顺序的情况下来支持较短的匹配搜索,而非较长的匹配搜索。

使用DFA引擎的程序主要有:awk,egrep,flex,lex,MySQL,Procmail等;

使用传统型NFA引擎的程序主要有:GNU Emacs,Java,ergp,less,more,.NET语言,PCRE library,Perl,PHP,Python,Ruby,sed,vi;

使用POSIX NFA引擎的程序主要有:mawk,Mortice Kern Systems’ utilities,GNU Emacs(使用时可以明确指定);

也有使用DFA/NFA混合的引擎:GNU awk,GNU grep/egrep,Tcl。

举例简单说明NFA与DFA工作的区别:

比如有字符串this is yansen’s blog,正则表达式为 /ya(msen|nsen|nsem)/ (不要在乎表达式怎么样,这里只是为了说明引擎间的工作区别)。 NFA工作方式如下,先在字符串中查找 y 然后匹配其后是否为 a ,如果是 a 则继续,查找其后是否为 m 如果不是则匹配其后是否为 n (此时淘汰msen选择支)。然后继续看其后是否依次为 s,e,接着测试是否为 n ,是 n 则匹配成功,不是则测试是否为 m 。为什么是 m ?因为 NFA 工作方式是以正则表达式为标准,反复测试字符串,这样同样一个字符串有可能被反复测试了很多次。

而DFA则不是如此,DFA会从 this 中 t 开始依次查找 y,定位到 y ,已知其后为a,则查看表达式是否有 a ,此处正好有a 。然后字符串a 后为n ,DFA依次测试表达式,此时 msen 不符合要求淘汰。nsen 和 nsem 符合要求,然后DFA依次检查字符串,检测到sen 中的 n 时只有nsen 分支符合,则匹配成功。

由此可以看出来,两种引擎的工作方式完全不同,一个(NFA)以表达式为主导,一个(DFA)以文本为主导。一般而论,DFA引擎则搜索更快一些。但是NFA以表达式为主导,反而更容易操纵,因此一般程序员更偏爱NFA引擎。 两种引擎各有所长,而真正的引用则取决与你的需要以及所使用的语言。

四、实现正则表达式的库:

正则表达式的具体实现通常指具体编程语言或工具所使用的库或模块。例如:

   - **PCRE (Perl Compatible Regular Expressions)**:广泛用于各种语言和工具中,提供了类似Perl语言正则表达式功能的实现。
   - **std::regex**:C++的正则表达式库,可以在C++程序中使用。
   - **re**:这是Python语言中的一个标准库,用于提供正则表达式的支持。
   - **java.util.regex**:Java语言中用于处理正则表达式的类库。
   - **RegExp**:JavaScript中内建的正则表达式支持。

五、正则表达式的语法

正则表达式的语法可以非常复杂,但以下是一些基本的组成元素:

1. **字面量** (Literals):

任何非特殊字符都会匹配它自己。

2. **元字符** (Metacharacters):

在正则表达式中有特殊含义的字符,

如:
   - . 表示任何单个字符(除了换行符)。
   - ^ 表示行的开始。
   - $ 表示行的结束。
   - * 表示前一个字符的0次或多次匹配。
   - + 表示前一个字符的1次或多次匹配。
   - ? 表示前一个字符的0次或1次匹配。
   - {n,m} 表示前一个字符至少n次,不超过m次的匹配。

3. **字符集** (Character classes):

定义一个字符集合,匹配该集合中的任意字符。

   - [abc] 将匹配 "a"、"b" 或 "c"。
   - [^abc] 将匹配 "a"、"b" 和 "c" 之外的任何字符。
   - [a-z] 匹配任何小写字母。
   - [A-Z] 匹配任何大写字母。
   - [0-9] 匹配任何数字。

4. **转义字符** (Escape character): 

\ 被用来转义特殊字符。

   - \t 表示制表符。
   - \n 表示换行符。
   - \\ 表示字面量的反斜杠。
   - \. 表示字面量的点(不再是元字符了)。

5. **锚点** (Anchors):

 \b 和 \B 表示单词的边界和非边界。

   - \b 匹配一个单词边界,即字与空格间的位置。
   - \B 匹配非单词边界。

6. **分组** (Grouping) 和 **捕获** (Capturing):

   - 使用小括号`()`可以将多个字符组成一个单元,这个单元可以用`*+`等元字符来整体匹配。
   - (abc) 表示匹配字面字符串 "abc"。
   - (a|b) 表示匹配 "a" 或 "b"。

7. **非捕获分组** (Non-capturing groups):

使用`(?: ... )`可以进行分组但不捕获匹配的子字符串。

8. **前向和后向断言** (Lookahead and Lookbehind assertions):

   - 前向肯定断言 (?=...) 匹配一个后面跟着特定模式的位置。
   - 前向否定断言 (?!...) 匹配一个后面不跟着特定模式的位置。
   - 后向肯定断言 (?<=...) 匹配一个前面是特定模式的位置。
   - 后向否定断言 (?<!...) 匹配一个前面不是特定模式的位置。

正则表达式在各种编程语言中都有广泛的支持,包括Python、Java、JavaScript、C#、PHP等。在不同的编程语言中,正则表达式的工作方式和性能上可能有所差异,但基本的语法规则是一致的。在实际使用中,由于正则表达式的复杂性,通常推荐先通过文档加深理解,并在在线测试工具上练习,以便熟练掌握其强大的功能。 

六、正则表达式用例

1. **验证电子邮件地址**:

   ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$

   - ^ 匹配输入字符串的开始位置。
   - [a-zA-Z0-9._%+-]+ 匹配前面的字符集合一次或多次(邮件用户名部分)。
   - @ 字面量字符 "@"。
   - [a-zA-Z0-9.-]+ 匹配邮件服务提供商名(域名前部)。
   - \. 字面量点,用来分隔域名的各部分。
   - [a-zA-Z]{2,} 匹配域名后缀(如.com、.org等),至少两个字符。
   - $ 匹配输入字符串的结束位置。

2. **匹配手机号码(以中国为例)**:

   ^1[3-9]\d{9}$

   - ^ 匹配输入字符串的开始位置。
   - 1 字面量数字 "1"。
   - [3-9] 匹配3到9之间的任一数字。(这假定手机号码第二位为3-9之间的数字)
   - \d{9} 匹配任意数字,连续9次。
   - $ 匹配输入字符串的结束位置。

3. **查找HTML标签**:

   <([a-z]+)([^<]+)*(?:>(.*)<\/\1>| *\/>)

   - < 开始的字面小于号。
   - ([a-z]+) 匹配并捕获一次或多次的小写字母(即标签名)。
   - ([^<]+)* 匹配除了小于号之外的任意字符,零次或多次。
   - (?: ... ) 是一个非捕获分组。
   - > 字面量大于号,结束标签的开始部分。
   - (.*) 匹配并捕获任意字符,零次或多次,直到闭标签前。
   - </\1> 中 \1 引用第一个捕获组,匹配相同的标签名。
   - | 表示或操作符,匹配前面或后面的表达式。
   - *\/> 匹配自闭合标签的结尾。

4. **匹配IPv4地址**:

   ^(\d{1,3}\.){3}\d{1,3}$

   - ^ 匹配输入字符串的开始位置。
   - (\d{1,3}\.){3} 单个数字字符重复1到3次,跟着点,这个模式重复3次(对应前三个数字及点)。
   - \d{1,3} 匹配1至3位数的数字字符。
   - $ 匹配输入字符串的结束位置。

5. **简单密码强度校验**:

   ^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{8,}$

   - ^ 匹配输入字符串的开始位置。
   - (?=.*[A-Za-z]) 前向断言,确保至少存在一个字母。
   - (?=.*\d) 前向断言,确保至少存在一个数字。
   - [A-Za-z\d]{8,} 匹配8个或更多的字母或数字。
   - $ 匹配输入字符串的结束位置。

每个用例都是根据具体需求制定的,可能会因应用的上下文和要求不同而有所变化。在使用这些正则表达式时,需谨慎考虑边界情况和特定语言实现的细微差别,并应在实际环境中进行充分测试。

相关链接:

正则表达式_百度百科 (baidu.com)

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

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

相关文章

短视频矩阵系统:赋予用户创造与分享的力量

在如今快节奏的社交网络时代&#xff0c;人们对于信息获取和娱乐方式的需求也逐渐发生了变化。作为当下最受欢迎的短视频平台之一&#xff0c;抖音短视频矩阵系统正以其独特的魅力和吸引力&#xff0c;深深地打动着亿万用户。 抖音短视频矩阵系统是一种基于移动端的短视频分享…

ros2+gazebo+urdf:ros2机器人使用gazebo的urdf文件中的<gazebo>部分官网资料

原文链接SDFormat extensions to URDF (the gazebo tag) — Documentation 注意了ros2的gazebo部分已经跟ros1的gazebo部分不一样了&#xff1a; Toggle navigation SpecificationAPIDocumentationDownload Back Edit Version: 1.6 Table of C…

Shell 脚本应用(四)

正则表达式概述 正则表达式又称正规表达式&#xff0c;常规表达式。在代码中常简写为regex&#xff0c;regexp 或RE.正则表达式 是使用单个字符串来描述&#xff0c;匹配一系列符合某个句法规则的字符串&#xff0c;简单来说&#xff0c;是一种匹配字符串 的方法&#xff0c;通…

文件夹共享功能的配置 以及Windows server2012防火墙的配置

目录 一. 配置文件夹共享功能 1.1 为什么需要配置文件夹共享功能 1.2 配置文件夹共享 1.3 访问共享文件夹 1.4 配置取消 用户名和密码认证 二. windows server 2012防火墙配置 思维导图 一. 配置文件夹共享功能 1.1 为什么需要配置文件夹共享功能 我们在工作和生活中经…

信号与线性系统翻转课堂笔记12——时域取样定理

信号与线性系统翻转课堂笔记12 The Flipped Classroom12 of Signals and Linear Systems 对应教材&#xff1a;《信号与线性系统分析&#xff08;第五版&#xff09;》高等教育出版社&#xff0c;吴大正著 一、要点 &#xff08;1&#xff09;了解信号取样的概念&#xff1…

智能优化算法应用:基于浣熊算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于浣熊算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于浣熊算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.浣熊算法4.实验参数设定5.算法结果6.参考文献7.MA…

【python与机器学习3】感知机和门电路:与门,或门,非门等

目录 1 电子和程序里的与门&#xff0c;非门&#xff0c;或门&#xff0c;与非门 &#xff0c;或非门&#xff0c;异或门 1.1 基础电路 1.2 所有的电路情况 1.3 电路的符号 1.4 各种电路对应的实际电路图 2 各种具体的电路 2.1 与门&#xff08;and gate&#xff09; 2…

什么是数据分析思维

参考 一文学会如何做电商数据分析&#xff08;附运营分析指标框架&#xff09; 电子商务该如何做数据分析&#xff1f;如何数据分析入门&#xff08;从各项指标表象进入&#xff09; https://www.processon.com/outline/6589838c3129f1550cc69950 数据分析步骤 什么是数据分析…

2024年元旦节放假通知

致尊敬的客户以及全体同仁&#xff1a; 旧岁已展千重锦&#xff0c;新年再进百尺竿。在这辞旧迎新之际&#xff0c;易天光通信提前祝您元旦快乐&#xff01;生意兴隆&#xff0c;身体健康&#xff0c;万事如意&#xff01;根据国家法定假期的规定&#xff0c;并结合公司实际情…

Elasticsearch8.x结合OpenAI CLIP模型实现图搜图及文搜图功能

前言 在当今大数据时代&#xff0c;搜索引擎已经是许多应用的核心组件之一&#xff0c;近年随着大模型以及AI技术&#xff08;如&#xff1a;自然语言处理NLP&#xff09;的流行&#xff0c;这些技术的结合将会创造出更多的应用场景&#xff0c;比如&#xff1a;电商商品搜索、…

centos 安装oracle 11.2.04 并配置数据库自启动操作记录,一次完成

环境&#xff1a; centos版本7.3&#xff0c;安装的有图形化界面 Oracle11.2.04&#xff0c;之所以选择这个版本是因为网上有人说11其他版本的在安装的过程中会出现这样或那样的问题&#xff0c;下载地址放到文章下面 步骤&#xff0c;按顺序&#xff1a; 1、创建安装Oracle…

nginx反向代理服务器及负载均衡服务配置

一、正向代理与反向代理 正向代理&#xff1a;是一个位于客户端和原始服务器(oricin server)之间的服务器&#xff0c;为了从原始服务器取得内容&#xff0c;客户端向代理发送一个请求并指定目标(原始服务器)&#xff0c;然后代理向原始服务器转交请求并将获得的内容返回给客户…

Tauri:构建高效安全的桌面应用程序 | 开源日报 No.124

tauri-apps/tauri Stars: 64.6k License: Apache-2.0 Tauri 是一个开源项目&#xff0c;它可以通过 Web 前端构建更小、更快和更安全的桌面应用程序。 该项目具有以下优势和特点&#xff1a; Tauri 可以帮助用户构建桌面应用程序&#xff0c;并使用 web 前端技术进行界面设计…

Bug:Too many open files【ulimit限制】

Bug&#xff1a;Too many open files 今天在开发某个下载功能时&#xff0c;发现文件总是下载到250多个程序就挂掉&#xff0c;同时会打崩服务器&#xff0c;查看错误日志发现报&#xff1a;too many open files. 思路&#xff1a;根据错误信息可以知道打开的文件数过多&#x…

k8s的二进制部署

k8s的二进制部署&#xff1a;源码包部署 k8smaster01: 20.0.0.101 kube-apiserver kube-controller-manager kube-scheduler etcd k8smaster02: 20.0.0.102 kube-apiserver kube-controller-manager kube-scheduler node节点01: 20.0.0.103 kubelet kube-proxy etcd node节点02…

2024 年 11 款最佳 Android 数据恢复软件应用

Android 设备上的数据丢失可能是一种令人痛苦的经历&#xff0c;通常会导致不可替代的信息瞬间消失。 意外删除、系统崩溃或格式错误都可能发生&#xff0c;重要数据的丢失可能会扰乱日常工作并影响您的工作效率。 幸运的是&#xff0c;技术进步带来了多种恢复解决方案&…

微信小程序预览pdf,修改pdf文件名

记录微信小程序预览pdf文件&#xff0c;修改pdf名字安卓和ios都可用。 1.安卓和苹果的效果 2.需要用到的api 1.wx.downloadFile wx.downloadFile 下载文件资源到本地。客户端直接发起一个 HTTPS GET 请求&#xff0c;返回文件的本地临时路径 (本地路径)&#xff0c;单次下载…

数据结构:图文详解 树与二叉树(树与二叉树的概念和性质,存储,遍历)

目录 一.树的概念 二.树中重要的概念 三.二叉树的概念 满二叉树 完全二叉树 四.二叉树的性质 五.二叉树的存储 六.二叉树的遍历 前序遍历 中序遍历 后序遍历 一.树的概念 树是一种非线性数据结构&#xff0c;它由节点和边组成。树的每个节点可以有零个或多个子节点…

深圳鼎信|输电线路防山火视频监控预警装置:森林火灾来袭,安全不留白!

受线路走廊制约和环保要求影响&#xff0c;输电线路大多建立在高山上&#xff0c;不仅可以减少地面障碍物和人类活动的干扰&#xff0c;还能提高线路的抗灾能力和可靠性。但同时也会面临其它的难题&#xff0c;例如森林火灾预防。今天&#xff0c;深圳鼎信智慧将从不同角度分析…

基于AR+地图导航的景区智慧导览设计

随着科技的飞速发展&#xff0c;智慧旅游已经成为现代旅游业的一个重要趋势。在这个背景下&#xff0c;景区智慧导览作为智慧旅游的核心组成部分&#xff0c;正逐渐受到越来越多游客的青睐。本文将深入探讨地图导航软件在景区智慧导览中的应用&#xff0c;并分析其为游客和景区…