正则入门到精通


![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/ee791b6fb74b4f649bdba48efea7c7ee.png

一、正则表达式入门​

正则表达式本质上是一串字符序列,用于定义一个文本模式。通过这个模式,我们可以指定要匹配的文本特征。例如,如果你想匹配一个以 “abc” 开头的字符串,正则表达式可以写作 “^abc”,其中 “^” 表示匹配字符串的开头。​

(一)基本字符匹配​

在正则表达式中,普通字符(如字母、数字)通常表示它们自身。例如,正则表达式 “abc” 可以匹配文本中的 “abc” 序列。如果文本是 “abcdef”,那么 “abc” 会匹配成功;但如果文本是 “defabc”,那么匹配失败,因为正则表达式是从左到右进行匹配的。​

案例(JavaScript):​

const text1 = "abcdef";const regex1 = /abc/;​console.log(regex1.test(text1)); // 输出: true​const text2 = "defabc";const regex2 = /abc/;​console.log(regex2.test(text2)); // 输出: false​

在上述代码中,/abc/是一个正则表达式字面量,test方法用于测试给定的字符串是否包含匹配正则表达式的文本。​

(二)特殊字符​

正则表达式中有一些特殊字符,它们具有特殊的含义。例如:​

“.”(点号):匹配任意单个字符(除了换行符)。例如,“a.c” 可以匹配 “abc”、“adc” 等,但不能匹配 “ac”。​
”(星号):表示前面的字符可以出现零次或多次。例如,“abc” 可以匹配 “ac”、“abc”、“abbc” 等。​
“+”(加号):表示前面的字符至少出现一次。例如,“ab+c” 可以匹配 “abc”、“abbc” 等,但不能匹配 “ac”。​
“?”(问号):表示前面的字符可以出现零次或一次。例如,“ab?c” 可以匹配 “ac” 和 “abc”。​
”(脱字符):用于匹配字符串的开头。例如,“abc” 表示匹配以 “abc” 开头的字符串。​
“​

” 表示匹配以 “abc” 结尾的字符串。​

// “.”的案例​const text3 = "a1c a2c a c";const regex3 = /a.c/;​console.log(text3.match(regex3)); // 输出: ["a1c"],注意:match方法默认只返回第一个匹配结果​// “*”的案例​const text4 = "ac abc abbc abbbc";const regex4 = /ab*c/;​console.log(text4.match(regex4)); // 输出: ["abbbc"]​// “+”的案例​const text5 = "abc abbc abbbc";const regex5 = /ab+c/;​console.log(text5.match(regex5)); // 输出: ["abbbc"]​// “?”的案例​const text6 = "ac abc";const regex6 = /ab?c/;​console.log(text6.match(regex6)); // 输出: ["abc"]​// “^”的案例​const text7 = ["abcdef", "defabc", "abc"];const regex7 = /^abc/;​text7.forEach(str => {​console.log(regex7.test(str));// 输出: true, false, true​});​​// “$”的案例​const text8 = ["abc", "defabc", "abcd"];const regex8 = /abc$/;​text8.forEach(str => {​console.log(regex8.test(str));// 输出: true, true, false​});

在这些案例中,match方法用于在字符串中查找所有匹配正则表达式的子字符串,并返回一个数组。如果没有找到匹配项,则返回null。test方法则用于判断字符串是否与正则表达式匹配,返回true或false。​

(三)字符集​

字符集用于匹配一组特定的字符。例如,“[abc]” 可以匹配 “a”、“b” 或 “c”。字符集还可以使用范围表示法,如 “[a-z]” 表示匹配任意一个小写字母,“[0-9]” 表示匹配任意一个数字。​

// 匹配元音字母​const text9 = "apple banana cherry";const regex9 = /[aeiou]/g;​console.log(text9.match(regex9));// 输出: ["a", "e", "a", "a", "e"],这里的“g”标志表示全局匹配,即找到所有匹配项​// 匹配数字​const text10 = "123abcABC";const regex10 = /[0-9]/g;​console.log(text10.match(regex10)); // 输出: ["1", "2", "3"]​// 匹配字母​const text11 = "123abcABC";const regex11 = /[a-zA-Z]/g;​console.log(text11.match(regex11)); // 输出: ["a", "b", "c", "A", "B", "C"]​

在上述代码中,正则表达式中的 “g” 标志是非常重要的,它使得match方法能够返回所有匹配的结果,而不仅仅是第一个。​

(四)分组​

分组是通过圆括号 “()” 来实现的。它可以将多个字符组合在一起,作为一个整体进行匹配。例如,“(abc)+” 表示匹配一个或多个 “abc” 序列。​

const text12 = "abcabcabc abcab ab";const regex12 = /(abc)+/g;​console.log(text12.match(regex12));// 输出: ["abcabcabc", "abcab"]​

在这个例子中,通过分组我们能够准确匹配由一个或多个 “abc” 序列组成的子字符串。​

二、正则表达式的进阶应用​

(一)匹配特定格式的文本​

正则表达式可以用来匹配各种特定格式的文本,如日期、电话号码、电子邮件地址等。例如,一个简单的电子邮件地址匹配正则表达式可以写作 “[a-zA-Z0-9_.±]+@[a-zA-Z0-9-]+.[a-zA-Z0-9-.]+”。这个表达式通过字符集和分组的方式,确保了电子邮件地址的基本格式。​

// 日期匹配​const text13 = "今天是2023-10-15,明天是2023-10-16";const regex13 = /\d{4}-\d{2}-\d{2}/g;​console.log(text13.match(regex13));// 输出: ["2023-10-15", "2023-10-16"]​// 电话号码匹配​const text14 = "联系电话:13800138000";const regex14 = /1\d{10}/;​console.log(text14.match(regex14)); // 输出: ["13800138000"]​// 电子邮件地址匹配​const text15 = "我的邮箱是example@example.com,另一个是test_123@test-company.co.uk";const regex15 = /[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+/g;​console.log(text15.match(regex15));// 输出: ["example@example.com", "test_123@test-company.co.uk"]​

这些案例展示了如何使用正则表达式在 JavaScript 中准确匹配常见的特定格式文本。​

(二)捕获与替换​

正则表达式不仅可以用于匹配文本,还可以用于捕获和替换文本。通过分组和捕获功能,我们可以提取文本中的特定部分,并进行替换操作。例如,在文本编辑器中,我们可以使用正则表达式查找所有以 “http://” 开头的链接,并将其替换为 “https://”。​

// 捕获域名部分并替换链接协议​const text16 = "请访问链接:http://example.com和http://test.com";const regex16 = /http://([a-zA-Z0-9-.]+)/g;const newText16 = text16.replace(regex16, "https://$1");​console.log(newText16);// 输出: 请访问链接:https://example.com和https://test.com​// 提取价格部分​const text17 = "苹果价格是10元,香蕉价格是5元";const regex17 = /价格是 (\d+) 元/g;const prices = text17.match(regex17);if (prices) {​prices.forEach(price => {const num = price.match(/\d+/)[0];​console.log(parseInt(num));// 输出: 10, 5​});}

在第一个替换案例中,replace方法接受一个正则表达式和一个替换字符串,其中 “$1” 表示引用第一个捕获组的内容。在第二个提取案例中,我们先通过正则表达式找到包含价格的子字符串,然后再进一步提取其中的数字。​

(三)贪婪与非贪婪匹配​

在正则表达式中,贪婪模式会尽可能多地匹配字符,而非贪婪模式则会尽可能少地匹配字符。例如,“ab” 是一个贪婪模式,它会匹配 “aabb” 中的 “aabb”;而 “a?b” 是一个非贪婪模式,它会匹配 “aabb” 中的 “ab” 和 “abb”。​

// 贪婪模式案例​const text18 = "aaaab";const regex18 = /a*b/;​console.log(text18.match(regex18)); // 输出: ["aaaab"]​// 非贪婪模式案例​const text19 = "aaaab";const regex19 = /a*?b/;​console.log(text19.match(regex19)); // 输出: ["ab"]​// 提取HTML标签内内容的案例​const text20 = "<div>content1</div><div>content2</div>";const greedyRegex = /<div>.*</div>/;const nonGreedyRegex = /<div>.*?</div>/g;​console.log(text20.match(greedyRegex));// 输出: ["<div>content1</div><div>content2</div>"]​console.log(text20.match(nonGreedyRegex));// 输出: ["<div>content1</div>", "<div>content2</div>"]​

通过这些案例,可以清晰地看到贪婪模式和非贪婪模式在匹配行为上的差异。​

三、正则表达式的高级技巧​

(一)前瞻与后顾​

前瞻(Lookahead)和后顾(Lookbehind)是正则表达式中的高级功能。它们允许我们在匹配时考虑后面的或前面的字符,但不将其包含在匹配结果中。例如,“(?=abc) def” 表示匹配 “def”,但前提是它后面跟着 “abc”。​

// 正向前瞻案例​const text21 = "defabc defxyz";const regex21 = /(?=abc)def/;​console.log(text21.match(regex21)); // 输出: ["def"]​// 正向后顾案例​const text22 = "abcdef xyzdef";const regex22 = /(?<=abc)def/;​console.log(text22.match(regex22)); // 输出: ["def"]​

在 JavaScript 中,正向后顾在某些环境(如 Chrome 浏览器)中支持有限,上述代码在支持正向后顾的环境中运行。​

(二)递归匹配​

递归匹配是一种强大的功能,可以用于匹配嵌套的结构,如括号嵌套。例如,“​

(?>[()]+∣(?R))∗

” 可以匹配嵌套的括号结构。​

const text23 = "((a + b) * (c - d))";const regex23 = /\((?>[^()]+|(?R))*\)/;​console.log(text23.match(regex23));// 输出: ["((a + b) * (c - d))"]​const text24 = "((a + b) * (c - d)";​console.log(text24.match(regex23));// 输出: null​

这个案例展示了递归匹配在处理嵌套结构时的有效性,以及在括号不完整时匹配失败的情况。​

(三)性能优化​

正则表达式的性能优化非常重要,尤其是在处理大量文本时。避免使用过于复杂的正则表达式,尽量减少回溯次数,可以提高匹配效率。​

// 低效的匹配单词方式​const longText = "这是一篇很长很长的文档,包含了很多单词,比如apple, banana, cherry等等";const inefficientRegex = /[a-zA-Z]+|[^a-zA-Z]+/g;​console.time("inefficientMatch");​longText.match(inefficientRegex);​console.timeEnd("inefficientMatch"); ​​// 高效的匹配单词方式(先分割)​console.time("efficientMatch");const words = longText.split(/[^a-zA-Z]+/).filter(word => word.length > 0);​console.timeEnd("efficientMatch"); ​​

在这个案例中,通过console.time和console.timeEnd方法可以对比两种方式的执行时间,明显可以看出先分割的方式在处理大量文本时性能更优。​

四、正则表达式的实践案例​

(一)数据清洗​

在数据处理中,正则表达式可以用于清洗文本数据。例如,去除文本中的多余空格、特殊字符等。​

// 去除多余空格​const text25 = " 你好,世界! ";const regex25 = /\s+/g;const cleanText25 = text25.replace(regex25, " ");​console.log(cleanText25);// 输出: 你好,世界!​// 去除特殊字符​const text26 = "!@#Hello, World$%^";const regex26 = /[!@#$%^&*(),.?":{}|<>]/g;const cleanText26 = text26.replace(regex26, "");​console.log(cleanText26);// 输出: Hello, World​

通过这些案例,我们可以看到正则表达式在数据清洗方面的便捷性。​

(二)文本提取​

从网页或文档中提取特定信息,如标题、链接、日期等,正则表达式是一个非常有用的工具。​

// 从网页中提取链接​const htmlText = "<a href=\"http://example1.com\">链接1</a><a href=\"http://example2.com\">链接2</a>";const linkRegex = /<a href="([^"]+)">/g;const links = htmlText.match(linkRegex);if (links) {​links.forEach(link => {const url = link.match(/"([^"]+)"/)[1];​console.log(url);// 输出: http://example1.com, http://example2.com​});}​​// 从文档中提取标题​const docText = "# 标题1\n内容1\n# 标题2\n内容2";const titleRegex = /^# (.*)$/gm;const titles = docText.match(titleRegex);if (titles) {​titles.forEach(title => {const titleText = title.match(/# (.*)/)[1];​console.log(titleText);// 输出: 标题1, 标题2​});}​​

这里的 “m” 标志表示多行匹配,使得正则表达式能够匹配每一行以 “# ” 开头的内容。​

(三)代码分析​

在代码编辑器中,正则表达式可以用于高亮显示特定的代码模式,如注释、关键字等。​

const code = "# 这是一个注释\nprint('Hello, World!')";const commentRegex = /#.*$/gm;const highlightedCode = code.replace(commentRegex, match => `<span style="color: green;">${match}</span>`);​console.log(highlightedCode);// 输出: <span style="color: green;"># 这是一个注释</span>​// print('Hello, World!')​const keywordRegex = /\b(print|def|class|if|else|for|while)\b/g;const keywordHighlightedCode = highlightedCode.replace(keywordRegex, match​
=> <span style="color: blue;">${match}</span>);​
console.log (keywordHighlightedCode);// 输出: # 这是一个注释​
// print('Hello, World!')​
// 匹配函数定义​
const code2 = "def add (a, b):\n    return a + b";const functionRegex = /def\s+(\w+)\s*

(.?)
:/gm;const functions = code2.match(functionRegex);if (functions) {​
functions.forEach(func => {const name = func.match(/def\s+(\w+)\s*

(.?)
:/)[1];​
console.log(函数名: ${name});// 输出:函数名: add​
});}// 匹配变量声明​
const code3 = "int num = 10;\nstring text = 'Hello';";const variableRegex = /\b\w+\s+\w+\s*=/g;const variables = code3.match (variableRegex);if (variables) {​
console.log (variables);// 输出: ["int num =", "string text ="]​
}​​

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

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

相关文章

对备忘录模式的理解

对备忘录模式的理解 一、场景1、题目【[来源](https://kamacoder.com/problempage.php?pid1095)】1.1 题目描述1.2 输入描述1.3 输出描述1.4 输入示例1.5 输出示例 2、理解需求 二、不采用备忘录设计模式1、代码2、问题3、错误的备忘录模式 三、采用备忘录设计模式1、代码1.1 …

86.方便的double转string属性 C#例子 WPF例子

在C#开发中&#xff0c;属性封装是一种常见的设计模式&#xff0c;它可以帮助我们更好地控制数据的访问和修改&#xff0c;同时提供更灵活的功能扩展。今天&#xff0c;我们就来探讨一个简单而优雅的属性封装示例&#xff1a;Power 和 PowerFormatted。 1. 问题背景 在实际开…

bun 版本管理工具 bum 安装与使用

在使用 node 的过程中&#xff0c;我们可能会因为版本更新或者不同项目的要求而频繁切换 node 版本&#xff0c;或者是希望使用更简单的方式安装不同版本的 node&#xff0c;这个时候我们一般会用到 nvm 或者类似的工具。 在我尝试使用 bun 的时候&#xff0c;安装前第一个想到…

GRE,MGRE

GRE&#xff1a;静态过程&#xff0c;有局限性 R1 &#xff1a; [r1]interface Tunnel 0/0/0 --- 创建一个虚拟的隧道接口 [r1-Tunnel0/0/0]ip address 192.168.3.1 24 --- 给隧道接口分配一个 IP 地址 [r1-Tunnel0/0/0]tunnel-protocol gre --- 定义接口的封装方式 [r1-Tun…

游戏无法启动?XINPUT1_3.dll 丢失的终极解决方案

当你兴奋地启动一款新游戏时&#xff0c;突然弹出一个错误提示——‘程序无法启动&#xff0c;因为计算机中丢失 XINPUT1_3.dll’。这种问题在 PC 玩家中非常常见&#xff0c;尤其是运行一些较老的游戏时。XINPUT1_3.dll 是 DirectX 运行库的关键组件&#xff0c;缺失会导致游戏…

用大语言模型学文学常识

李白的诗句“右军本清真”中的“清真”并非指伊斯兰教信仰&#xff0c;而是对王羲之&#xff08;王右军&#xff09;人格和艺术境界的赞美。以下是对这一问题的详细分析&#xff1a; “清真”的古代含义 在魏晋至唐代的语境中&#xff0c;“清真”一词多用于形容人的品格高洁、…

css炫酷的3D水波纹文字效果实现详解

炫酷的3D水波纹文字效果实现详解 这里写目录标题 炫酷的3D水波纹文字效果实现详解项目概述技术栈核心实现1. 基础布局2. 渐变背景3. 文字效果实现3.1 基础样式3.2 文字漂浮动画 4. 水波纹效果4.1 模糊效果4.2 水波动画 5. 交互效果 技术要点项目难点与解决方案总结 项目概述 在…

八、重学C++—动态多态(运行期)

上一章节&#xff1a; 七、重学C—静态多态&#xff08;编译期&#xff09;-CSDN博客https://blog.csdn.net/weixin_36323170/article/details/146999362?spm1001.2014.3001.5502 本章节代码&#xff1a; cpp/dynamicPolymorphic.cpp CuiQingCheng/cppstudy - 码云 - 开源中…

eventEmitter实现

没有做任何异常处理,简单模拟实现 事件对象的每一个事件都对应一个数组 /*__events {"事件1":[cb1,cb2],"事件2":[cb3,cb4],"事件3":[...],"事件4":[...],};*/class E{__events {};constructor(){}//注册监听回调on(type , callbac…

Mysql 中 B 树 vs B+ 树

&#x1f333; 什么是 B树 和 B树&#xff1f; 它们都是多路平衡查找树&#xff08;M-Way Search Tree&#xff09;&#xff0c;用于提升磁盘读写效率&#xff0c;常用于数据库&#xff08;如 MySQL&#xff09;、操作系统中的索引结构。 &#x1f50d; B树 和 B树 的核心区别…

蓝桥云客---九宫幻方

1.九宫幻方 - 蓝桥云课 九宫幻方 题目描述 小明最近在教邻居家的小朋友小学奥数&#xff0c;而最近正好讲述到了三阶幻方这个部分&#xff0c;三阶幻方指的是将1~9不重复的填入一个3 * 3的矩阵当中&#xff0c;使得每一行、每一列和每一条对角线的和都是相同的。 三阶幻方又…

OrangePi5Plus开发板不能正确识别USB 3.0 设备 (绿联HUB和Camera)

1、先插好上电&#xff08;可正确识别&#xff09; 2、上电开机后插入USB 3.0 设备&#xff0c;报错如下&#xff0c;只能检测到USB2.0--480M&#xff0c;识别不到USB3.0-5Gbps&#xff0c;重新插拔也不行 Apr 4 21:30:00 orangepi5plus kernel: [ 423.575966] usb 5-1: re…

LiveData 和 MutableLiveData 的区别

LiveData 和 MutableLiveData 的区别 主要在于是否可以修改数据&#xff0c;但它们的工作原理基本相同。下面我们深入对比它们的行为、特性&#xff0c;以及它们在 ViewModel 和 UI 层中的使用方式。 1. LiveData 和 MutableLiveData 的基本区别 特性LiveDataMutableLiveData可…

SDK中窗口调用

存在窗口A和B的win32程序 , 当点击窗口A中的按钮后会弹出窗口B #include <windows.h>// 窗口 B 的窗口过程 LRESULT CALLBACK WindowProcB(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {switch (uMsg) {case WM_DESTROY:PostQuitMessage(0);break;default:ret…

进行性核上性麻痹:饮食调理为健康护航

进行性核上性麻痹是一种复杂的神经退行性疾病&#xff0c;目前虽无法根治&#xff0c;但合理的健康饮食有助于缓解症状、提高患者生活质量。 高蛋白质食物在患者饮食中占据重要地位。鱼肉&#xff0c;尤其是富含 Omega-3 脂肪酸的三文鱼、鳕鱼等&#xff0c;不仅蛋白质含量丰富…

【Windows+Cursor】从0到1配置Arxiv MCP Server,实现论文自主查询、下载、分析、综述生成

1. 安装UV Installation | uv powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex" 将安装路径添加到环境变量 C:\Users\xxxxxx\.local\bin 2. git clone 代码 git clone https://github.com/blazickjp/arxiv-mcp-server.git…

WPF 教程:给 TreeView 添加 SelectedItem 双向绑定支持(MVVM-Friendly)

&#x1f332;WPF 教程&#xff1a;给 TreeView 添加 SelectedItem 双向绑定支持&#xff08;MVVM-Friendly&#xff09; 在 WPF 的 MVVM 应用中&#xff0c;TreeView 是非常常见的控件&#xff0c;但它有个“顽固”的缺陷&#xff1a; ❗它的 SelectedItem 不是依赖属性&…

Linux环境下内存错误问题排查与修复

最近这几天服务器总是掉线&#xff0c;要查一下服务器的问题。可以首先查看一下计算机硬件&#xff0c;这是一台某鱼上拼凑的服务器&#xff1a; sudo lshw -shortH/W path Device Class Description system NF5270M3 (To be filled by O…

函数和模式化——python

一、模块和包 将一段代码保存为应该扩展名为.py 的文件&#xff0c;该文件就是模块。Python中的模块分为三种&#xff0c;分别为&#xff1a;内置模块、第三方模块和自定义模块。 内置模块和第三方模块又称为库内置模块&#xff0c;有 python 解释器自带&#xff0c;不用单独安…

windows下载安装远程桌面工具RealVNC-Server教程(RealVNC_E4_6_1版带注册码)

文章目录 前言一、下载安装包二、安装步骤三、使用VNC-Viewer客户端远程连接&#xff0c;输入ip地址&#xff0c;密码完成连接 前言 在现代工作和生活中&#xff0c;远程控制软件为我们带来了极大的便利。RealVNC - Server 是一款功能强大的远程控制服务器软件&#xff0c;通过…