Rust语言中Regex正则表达式,匹配和查找替换等

官方仓库:https://crates.io/crates/regex

文档地址:regex - Rust 

github仓库地址:GitHub - rust-lang/regex: An implementation of regular expressions for Rust. This implementation uses finite automata and guarantees linear time matching on all inputs.

在线体验地址:Rust Playground

直接使用下面代码测试环境:

use regex::Regex;fn main() {// try using the `regex` crate herelet re = Regex::new(r"[1-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[1-9]{1,3}").unwrap();let text = "这是一段用于演示匹配的文本。192.168.0.1 是一个合法的 IP 地址,然而 900.300.700.600 不是.";for cap in re.captures_iter(text) {println!("匹配到合法的IP地址: {}", &cap[0]);}
}

点击左上角的RUN:就可以看到匹配结果

安装regex

直接在rust项目目录中运行:

cargo add regex

或者编辑 Cargo.toml 文件添加:

[dependencies]
regex = "1.10.4"

然后运行:cargo run

使用正则表达式

创建正则表达式对象:

let re = Regex::new(r"(\d{4})-(\d{2})-(\d{2})").unwrap();

1.是否匹配:is_match

判断字符串是否和正则表达式匹配,是的话返回true,不是的话返回false

use regex::Regex;fn main() {println!("Hello, world!");//let re = Regex::new(r"^\d{4}-\d{2}-\d{2}$").unwrap();let date = "today is 2024-03-27";if re.is_match(date) {println!("完全匹配")} else {println!("不匹配")}
}

2.获取分组匹配到的项: captures_iter | captures

captures:返回与文本中最左边的第一个匹配相对应的捕获组。捕获组 0 始终对应于整个匹配。如果找不到匹配,则不返回任何内容。

captures_iter:返回文本中匹配的所有非重叠捕获组的迭代器。这在操作上与 find_iter 相同,除了它产生关于捕获组匹配的信息。

captures_iter可以获取到匹配到的每一项,可以通过遍历拿到匹配的结果,如果正则里面有使用分组()来匹配内容,可以通过遍历匹配的结果,通过下表来获取分组内容。

use regex::Regex;fn main() {println!("Hello, world!");let re = Regex::new(r"\d{4}-\d{2}-\d{2}").unwrap();let date = "today is 2024-03-27, yesterday is 2023-11-23";for cap in re.captures_iter(date) {println!("匹配到的结果是:{}", &cap[0]);}
}// 输出结果
匹配到的结果是:2024-03-27
匹配到的结果是:2023-11-23

不实用分组的匹配结果:captures (只能获取到匹配的第一个内容)

use regex::Regex;fn main() {println!("Hello, world!");let re = Regex::new(r"\d{4}-\d{2}-\d{2}").unwrap();let date = "today is 2024-03-27, yesterday is 2023-11-23";let res = re.captures(date).unwrap();println!("res is {}", &res[0]);
}// 输出结果
res is 2024-03-27

 使用分组正则表达式获取分组后的匹配结果:

use regex::Regex;fn main() {println!("Hello, world!");let re = Regex::new(r"(\d{4})-(\d{2})-(\d{2})").unwrap();let date = "today is 2024-03-27, yesterday is 2023-11-23";for cap in re.captures_iter(date) {println!("匹配到的结果是:{} {} {}", &cap[0], &cap[1], &cap[2]);}
}// 输出结果
匹配到的结果是:2024-03-27 2024 03
匹配到的结果是:2023-11-23 2023 11

3.替换匹配的内容:replace  和  replace_all

replace是替换一次,replace_all是替换所有匹配到的内容。

replace替换一次:

use regex::Regex;fn main() {println!("Hello, world!");let re = Regex::new(r"\d{4}-\d{2}-\d{2}").unwrap();let date = "today is 2024-03-27, yesterday is 2023-11-23";let res = re.replace(date, "2020-02-11");println!("replace result is:{}", res);
}// 输出结果
replace result is:today is 2020-02-11, yesterday is 2023-11-23

replace_all替换所有:

use regex::Regex;fn main() {println!("Hello, world!");let re = Regex::new(r"\d{4}-\d{2}-\d{2}").unwrap();let date = "today is 2024-03-27, yesterday is 2023-11-23";let res = re.replace_all(date, "2020-02-11");println!("replace result is:{}", res);
}// 输出结果
replace result is:today is 2020-02-11, yesterday is 2020-02-11

4.查找正则匹配的内容:find 和 find_iter

find:返回文本中最左边第一个匹配的开始和结束字节范围。如果不存在匹配,则返回 None。请注意,这应该只在您想要发现匹配的位置时使用。如果使用 is_match,测试匹配的存在会更快。

use regex::Regex;fn main() {println!("Hello, world!");let re = Regex::new(r"\d{4}-\d{2}-\d{2}").unwrap();let date = "today is 2024-03-27, yesterday is 2023-11-23";let res = re.find(date).unwrap();println!("find result is:{}", res.as_str());
}// 输出
find result is:2024-03-27

find_iter:text中每个连续的非重叠匹配返回一个迭代器,返回相对于 text 的起始和结束字节索引。

use regex::Regex;fn main() {println!("Hello, world!");let re = Regex::new(r"\d{4}-\d{2}-\d{2}").unwrap();let date = "today is 2024-03-27, yesterday is 2023-11-23";for fin in re.find_iter(date){println!("find result is:{}", fin.as_str());}
}// 输出结果
find result is:2024-03-27
find result is:2023-11-23

5.分割匹配的内容:split 和 splitn

split:返回由匹配的正则表达式分隔的文本子字符串的迭代器。也就是说,迭代器的每个元素对应于正则表达式不匹配的文本。此方法不会复制给定的文本。

use regex::Regex;fn main() {println!("Hello, world!");let re = Regex::new(r"[ \t]+").unwrap();let fields: Vec<&str> = re.split("a b \t  c\td    e").collect();println!("split result is:{:?}", fields)
}// 输出结果
split result is:["a", "b", "c", "d", "e"]

splitn:返回最多有限个文本子字符串的迭代器,这些子字符串由正则表达式的匹配项分隔。(限制为0将不会返回任何子字符串。)也就是说,迭代器的每个元素对应于正则表达式不匹配的文本。字符串中未被拆分的剩余部分将是迭代器中的最后一个元素。

use regex::Regex;fn main() {println!("Hello, world!");let re = Regex::new(r"\W+").unwrap();let fields: Vec<&str> = re.splitn("Hey! How are you?", 3).collect();println!("splitn result is:{:?}", fields)
}// 输出结果
splitn result is:["Hey", "How", "are you?"]

高级或“低级”搜索方法

shortest_match:返回给定文本中匹配的结束位置。

该方法可以具有与 is_match 相同的性能特征,除了它提供了匹配的结束位置。特别是,返回的位置可能比通过 Regex::find 找到的最左边第一个匹配的正确结尾要短。

注意,不能保证这个例程找到最短或“最早”的可能匹配。相反,这个 API 的主要思想是,它返回内部正则表达式引擎确定发生匹配的点的偏移量。这可能因使用的内部正则表达式引擎而异,因此偏移量本身可能会改变。

通常,a+ 会匹配某个文本中 a 的整个第一个序列,但是shortest_match 一看到第一个 a 就会放弃:

use regex::Regex;fn main() {println!("Hello, world!");let text = "aaaaa";let pos = Regex::new(r"a+").unwrap().shortest_match(text).unwrap();println!("shortest match is:{}", pos)
}// 输出结果
shortest match is:1

shortest_match_at:返回与 shortest_match 相同的值,但从给定的偏移量开始搜索。

起点的意义在于它考虑了周围的环境。例如,\A 定位点只能在 start == 0 时匹配。

use regex::Regex;fn main() {println!("Hello, world!");let re = Regex::new(r"\d+").unwrap();// 在字符串中查找最短匹配let text = "123456789";let shortest_match = re.shortest_match_at(text, 0).unwrap();println!("Shortest match found at index {}", shortest_match);
}// 输出结果
Shortest match found at index 1

is_match_at:返回与 is_match 相同的值,但从给定的偏移量开始搜索。

起点的意义在于它考虑了周围的环境。例如,\A 锚点只能在 start == 0 时匹配。

use regex::Regex;fn main() {println!("Hello, world!");let re = Regex::new(r"\d{3}-\d{2}-\d{4}").unwrap();let s = "123-45-6789";// 使用is_match_at方法判断字符串是否匹配正则表达式if re.is_match_at(s, 0) {println!("Matched!");} else {println!("Not matched!");}
}// 输出结果
Matched!

find_at:返回与 find 相同的值,但从给定的偏移量开始搜索。

起点的意义在于它考虑了周围的环境。例如,\A 锚点只能在 start == 0 时匹配。

use regex::Regex;fn main() {println!("Hello, world!");let s = "hello world";let re = Regex::new(r"world").unwrap();// 使用find_at方法查找字符串中第一个匹配正则表达式的位置let pos = re.find_at(s, 0).unwrap().start();// 输出匹配位置println!("Match found at position: {}", pos);
}// 输出结果
Match found at position: 6

辅助方法

as_str 方法:返回该正则表达式的原始字符串。

use regex::Regex;fn main() {println!("Hello, world!");let re = Regex::new(r"\d+").unwrap();let text = "2021-08-01";let result = re.find(text).unwrap();println!("{}", result.as_str());
}// 输出结果
2021

captures_len 方法:返回捕获的数量。 

正则匹配规则

下面说明了一些常用的正则匹配规则:

符号描述说明
^匹配一个字符串的起始字符如果多行标志被设置为 true,那么也匹配换行符后紧跟的位置。
$匹配一个字符串的结尾字符如果多行标志被设置为 true,那么也匹配换行符前的位置。
\b匹配一个单词的边界-
\B匹配单词边界相当于\b匹配的反集

限定符: 

符号描述说明
?匹配该限定符前的字符01等价于 {0,1},如 colou?r 可以匹配colourcolor
+匹配该限定符前的字符1等价于 {1,},如 hel+o可以匹配helohellohelllo、…
*匹配该限定符前的字符0等价于 {0,},如 hel*o可以匹配heohelohellohelllo、…
{n}匹配该限定符前的字符n如 hel{2}o只可以匹配hello
{n,}匹配该限定符前的字符最少n次如 hel{2,}o可以匹配hellohelllo、…
{n,m}匹配该限定符前的字符最少n次最多m次如 hel{2,3}o只可以匹配hello 和 helllo

单个字符:

符号描述说明
\d匹配任意数字
\s匹配任意空白符
\w匹配任意字母、数字、下划线、汉字等
\D匹配任意数字
\S匹配任意空白符
\W匹配除了字母、数字、下划线、汉字以外的字符
.匹配除了换行符以外的任意字符
形式描述说明
[A-Z]区间匹配,匹配字母表该区间所有大写字母[C-F]匹配字符C、D、E、F
[a-z]区间匹配,匹配字母表该区间所有小写字母[c-f]匹配字符c、d、e、f
[0-9]区间匹配,匹配该区间内的所有数字[3-6]匹配字符3、4、5、6
[ABCD]列表匹配,匹配[]中列出的所有字母如这里列出的A、B、C、D都会被匹配
[^ABCD]列表排除,匹配除了[]中列出的字符外的所有字符如这里列出的A、B、C、D都会被排除而匹配其它字符

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

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

相关文章

LoadBalance 负载均衡服务调用

前身:Ribbon LB负载均衡(Load Balance)是什么 简单的说就是将用户的请求平摊的分配到多个服务上&#xff0c;从而达到系统的HA&#xff08;高可用&#xff09;&#xff0c;常见的负载均衡有软件Nginx&#xff0c;LVS&#xff0c;硬件 F5等 spring-cloud-starter-loadbalancer组…

OSG编程指南<二十一>:OSG视图与相机视点更新设置及OSG宽屏变形

1、概述 什么是视图?在《OpenGL 编程指南》中有下面的比喻,从笔者开始学习图形学就影响深刻,相信对读者学习场景管理也会非常有帮助。 产生目标场景视图的变换过程类似于用相机进行拍照,主要有如下的步骤: (1)把照相机固定在三脚架上,让它对准场景(视图变换)。 (2)…

【办公类-21-11】 20240327三级育婴师 多个二级文件夹的docx合并成docx有页码,转PDF

背景展示&#xff1a;有页码的操作题 背景需求&#xff1a; 实操课终于全部结束了&#xff0c;把考试内容&#xff08;docx&#xff09;都写好了 【办公类-21-10】三级育婴师 视频转文字docx&#xff08;等线小五单倍行距&#xff09;&#xff0c;批量改成“宋体小四、1.5倍行…

洛谷day3

B2053 求一元二次方程 - 洛谷 掌握printf用法&#xff1b; #include <iostream> #include <cmath> using namespace std; double a,b,c; double delta; double x1,x2;int main() {cin>>a>>b>>c;delta b*b-4*a*c;if(delta>0){x1 (-bsqrt…

从根本上优雅地解决 VSCode 中的 Python 模块导入问题

整体概述&#xff1a; 在我尝试运行 test_deal_file.py 时&#xff0c;我遇到了一个 ModuleNotFoundError 错误&#xff0c;Python告诉我找不到名为 controllers 的模块。这意味着我无法从 deal_file.py 中导入 read_excel 函数。 为了解决这个问题&#xff0c;我尝试了几种方法…

JAVA面试大全之JVM和调优篇

目录 1、类加载机制 1.1、类加载的生命周期&#xff1f; 1.2、类加载器的层次? 1.3、Class.forName()和ClassLoader.loadClass()区别? 1.4、JVM有哪些类加载机制&#xff1f; 2、内存结构 2.1、说说JVM内存整体的结构&#xff1f;线程私有还是共享的&#xff1f; 2.2…

Rust使用原始字符串字面量实现Regex双引号嵌套双引号正则匹配

rust使用Regex实现正则匹配的时候&#xff0c;如果想实现匹配双引号&#xff0c;就需要使用原始字符串字面量&#xff0c;不然无法使用双引号嵌套的。r#"..."# 就表示原始字符串字面量。 比如使用双引号匹配&#xff1a; use regex::Regex;fn main() {println!(&qu…

【性能优化】 【回溯】 【字符串】1307. 口算难题

作者推荐 视频算法专题 本文涉及知识点 数学 回溯 字符串 性能优化 LeetCode1307. 口算难题 给你一个方程&#xff0c;左边用 words 表示&#xff0c;右边用 result 表示。 你需要根据以下规则检查方程是否可解&#xff1a; 每个字符都会被解码成一位数字&#xff08;0 - …

2024年云计算使用报告,89%组织用多云,25%广泛使用生成式AI,45%需要跨云数据集成,节省成本是云首要因素

备注&#xff1a;本文来自Flexera2024年的云现状调研报告的翻译。原报告地址&#xff1a; https://info.flexera.com/CM-REPORT-State-of-the-Cloud Flexera是一家专注于做SaaS的IT解决方案公司&#xff0c;有30年发展历史&#xff0c;5万名客户&#xff0c;1300名员工。Flex…

夜莺浏览日志、filebeat采集日志(四)

文章目录 一、elasticsearch二、filebeat三、日志分析 一、elasticsearch docker启动 docker run -d -p 9200:9200 -p 9300:9300 --restartalways -e ES_JAVA_OPTS"-Xms512m -Xmx512m" \ -e discovery.typesingle-node -e xpack.security.enabledtrue -e ELASTIC_P…

使用GO对PostgreSQL进行有意思的多线程压测

前言 针对PostgreSQL进行压缩&#xff0c;有很多相关的工具。有同学又要问了&#xff0c;为何还要再搞一个&#xff1f;比如&#xff0c;pgbench, sysbench之类的&#xff0c;已经很强大了。是的&#xff0c;它们都很强大。但有时候&#xff0c;在一些特殊的场景&#xff0c;可…

Django开发复盘

一、URL 对于一个不会写正则表达式的蒟蒻来说&#xff0c;在urls.py中就只能傻傻的写死名字&#xff0c;但是即便这样&#xff0c;还会有很多相对路径和绝对路径的问题&#xff08;相对ip端口的路径&#xff09;&#xff0c;因为我们网页中涉及到页面跳转&#xff0c;涉及到发送…

Tuxera for Mac2024免费读写硬盘U盘工具

作为软件产品专家&#xff0c;我对各类软件都有较为深入的了解&#xff0c;下面介绍Tuxera for Mac这款读写硬盘/U盘工具的相关信息&#xff1a; Tuxera for Mac是一款高效稳定的NTFS读写工具&#xff0c;专为解决Mac系统无法直接读写NTFS格式驱动器的问题而设计。它提供了完整…

Android 自定义EditText

文章目录 Android 自定义EditText概述源码可清空内容的EditText可显示密码的EditText 使用源码下载 Android 自定义EditText 概述 定义一款可清空内容的 ClearEditText 和可显示密码的 PasswordEditText&#xff0c;支持修改提示图标和大小、背景图片等。 源码 基类&#xf…

实现商铺和缓存与数据库双写一致

2.4 实现商铺和缓存与数据库双写一致 核心思路如下&#xff1a; 修改ShopController中的业务逻辑&#xff0c;满足下面的需求&#xff1a; 根据id查询店铺时&#xff0c;如果缓存未命中&#xff0c;则查询数据库&#xff0c;将数据库结果写入缓存&#xff0c;并设置超时时间…

ssm小区车库停车系统开发mysql数据库web结构java编程计算机网页源码eclipse项目

一、源码特点 ssm小区车库停车系统是一套完善的信息系统&#xff0c;结合springMVC框架完成本系统&#xff0c;对理解JSP java编程开发语言有帮助系统采用SSM框架&#xff08;MVC模式开发&#xff09;&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模…

如何在家中使用手机平板电脑 公司iStoreOS软路由实现远程桌面

文章目录 简介一、配置远程桌面公网地址二、家中使用永久固定地址 访问公司电脑**具体操作方法是&#xff1a;** 简介 软路由是PC的硬件加上路由系统来实现路由器的功能&#xff0c;也可以说是使用软件达成路由功能的路由器。 使用软路由控制局域网内计算机的好处&#xff1a…

HCIA-Datacom实验_03_实验一:华为VRP系统基本操作

1.运行eNSP&#xff0c;设置-界面设置-自定义界面-设备标签&#xff0c;“总显示接口标签” 打钩。 2.按照实验拓扑添加设备 注&#xff1a;如果是真实环境&#xff0c;需要接两条线&#xff1a; &#xff08;1&#xff09;串口线&#xff1a;电脑USB口到网络设备Console口&am…

Windows下载使用nc(netcat)命令

‘nc’ 不是内部或外部命令&#xff0c;也不是可运行的程序&#xff1f; 点击链接地址&#xff0c;下载压缩包。 完成后解压 使用方式&#xff08;三种&#xff09;&#xff1a; 1、直接双击exe使用 2、把这个exe放到cmd启动的默认路径下 放到默认路径下&#xff0c;使用nc&a…

MySQL高级语句(二)

一、前期准备工作 1.1 登陆mysql&#xff0c;查看数据表 1.2 显示所有表 1.3 创建guigui表并插入数据 1.4 创建ky35表格并插入数据 二、子连接 子查询也被称作内查询或者嵌套查询&#xff0c;是指在一个查询语句里面还嵌套着另一个查询语句。子查询语句是先于主查询语句被执行的…