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.mzph.cn/news/775417.shtml

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

相关文章

8.HelloWorld小案例

文章目录 一、Java程序开发运行流程如何理解编译&#xff1f; 二、HelloWorld案例的编写1、新建文本文档文件&#xff0c;修改名称为HelloWorld.java。2、用记事本打开HelloWorld.java文件&#xff0c;输写程序内容。代码要跟我编写的完全保持一致。3、ctrl s 保存&#xff0c…

CSS面试题常用知识总结day02

大家好我是没钱的君子下流坯&#xff0c;用自己的话解释自己的知识 前端行业下坡路&#xff0c;甚至可说前端已死&#xff0c;我还想在前段行业在干下去&#xff0c;所以从新开始储备自己的知识。 从CSS——>Javascript——>VUE2——>Vuex、VueRouter、webpack——>…

从MVC 到DDD 架构

目录 一、前言 二、MVC架构 三、DDD架构 四、我为什么会使用DDD&#xff1f; 五、DDD架构分层 一、前言 最近在做一个项目&#xff0c;使用的是DDD架构思&#xff0c;觉得很不错&#xff0c;在此记录下。 二、MVC架构 MVC是一种经典的软件架构模式&#xff0c;主要用于…

前端框架的简单介绍

html html-结构 盖房子之前先划三室二厅 &#xff08;超文本标记语言&#xff09;(可以实现一切的文本) css css-样式 在房里添家具 &#xff08;层叠样式单&#xff09;(化妆在脸上叠加) javascript(js) javascript(js)-交互(行为) 我点击你打开 供显示信息的元…

http模块 url对象的主要属性

在 Node.js 中&#xff0c;URL 对象是一个内置类&#xff0c;用于解析和操作 URL 字符串。URL 对象具有多个属性&#xff0c;这些属性提供了对 URL 不同部分的访问。以下是URL对象的一些主要属性及其含义&#xff1a; &#xff08;1&#xff09;href 返回完整的 URL 字符串。…

【爬虫基础】第5讲 AJAX动态页面的数据获取

静态&#xff1a;访问地址栏里的数据就可以获取到想要的数据 动态&#xff1a;访问地址栏里的数据获取不到想要的数据 解决方案&#xff1a;抓包 打开浏览器的开发者工具-network-xhr,找到可以获取到数据的URL访问即可 获取url地址 代码实现&#xff1a; from urllib.request…

aws 入门篇 01.aws学习的方法论

aws入门篇 01.aws学习的方法论 第1章 aws学习的方法论 aws的服务很多&#xff0c;现在应该有100多个服务了&#xff0c;怎么来学习aws呢&#xff1f; 这几年也使用了一些aws的服务&#xff0c;谈谈自己对学习aws的理解。 1.先横向&#xff0c;后纵深 比如说&#xff0c;aws最…

自动驾驶传感器:惯性导航IMU原理

自动驾驶传感器&#xff1a;惯性导航IMU原理 附赠自动驾驶学习资料和量产经验&#xff1a;链接 组合导航里包含了GNSS卫星导航模块与IMU惯性导航模块&#xff0c;前一篇文章写了GNSS模块&#xff0c;本章写IMU惯导&#xff0c;也是本系列最后一篇文章。 1. 惯性测量单元&…

瑞_23种设计模式_观察者模式

文章目录 1 观察者模式&#xff08;Observer Pattern&#xff09;1.1 介绍1.2 概述1.3 观察者模式的结构1.4 观察者模式的优缺点1.5 观察者模式的使用场景 2 案例一2.1 需求2.2 代码实现 3 案例二3.1 需求3.2 代码实现 4 JDK中提供的观察者模式实现 ★4.1 Observable类4.2 Obse…

05. 【Android教程】Android 程序签名打包

在上一章&#xff0c;我们创建了自己的 Android 工程&#xff0c;并成功的在模拟器中运行起来。同时提到&#xff0c;工程目录中有一个 bin 目录&#xff0c;运行之后我们可以在此目录下找到我们的 apk。那么不难想到&#xff0c;我们在点“Run”之后&#xff0c;系统会编译我们…

蓝桥杯嵌入式之串口(中断读取)

一、CUbeMX开启串口 1.开启串口USART1 记得手动开起PA9、PA10 2.配置波特率、开启串口中断 3.初始化开启接收中断 定于接收缓存区接收长度&#xff08;单位字节&#xff09; 4.在接收事件回调函数中进行操作 sscanf((char*)usart_box,"%4s",temp1); //只取收到的…

以太网链路聚合——增加带宽,解决生成树收敛慢的问题

目录 一.对STP生成树的补充 1.STP接口状态 2.STP生成树的改进 二.网络可靠性 1.单板可靠性 2.设备可靠性 3.链路可靠性 三.链路聚合 1.多条链路聚合增加带宽 2.链路聚合术语 四.链路聚合模式 1.手动模式 2.LASP模式 &#xff08;1).LASP术语 &#xff08;2&…

使用itext-core生成PDF

1、添加引用依赖包 <dependency><groupId>com.itextpdf</groupId><artifactId>itext-core</artifactId><version>8.0.3</version><type>pom</type></dependency> 2、上代码 package com.student.demo.pdf;impor…

什么是RISC-V?开源 ISA 如何重塑未来的处理器设计

RISC-V代表了处理器架构的范式转变&#xff0c;特点是其开源模型简化了设计理念并促进了全球community-driven的开发。RISC-V导致了处理器技术发展前进方式的重大转变&#xff0c;提供了一个不受传统复杂性阻碍的全新视角。 RISC-V起源于加州大学伯克利分校的学术起点&#xff…

逐步学习Go-协程goroutine

参考&#xff1a;逐步学习Go-协程goroutine – FOF编程网 什么是线程&#xff1f; 简单来说线程就是现代操作系统使用CPU的基本单元。线程基本包括了线程ID&#xff0c;程序计数器&#xff0c;寄存器和线程栈。线程共享进程的代码区&#xff0c;数据区和操作系统的资源。 线…

前端学习-01:Windows 安装 npm 教程

一、安装 Node.js Node.js 官方下载地址&#xff1a;点击这里点击绿色的"Download Node.js vxxxx"下载完成后双击开始安装点击 Next 接受协议&#xff0c;点击 Next 点击 Change&#xff0c;自定义安装目录&#xff0c;然后点击 Next 所有默认全部安装即可&#xff…

在 Linux CentOS 中安装 Docker Engine(Dockers 引擎)【图文详解】

官方文档&#xff1a;https://docs.docker.com/engine/install/centos/ 操作系统要求 如果我们要在 CentOS 中安装 Docker 引擎&#xff0c;那么 CentOS 操作系统需要是以下版本之一的&#xff0c;且是处于维护的 CentOS 版本&#xff1a; CentOS 7CentOS Stream 8CentOS Str…

【Web应用技术基础】CSS(4)——背景样式

第1题&#xff1a;背景颜色 .html <!DOCTYPE html> <html><head><meta charset"utf-8"><title>Hello World</title><link rel"stylesheet" href"step1/CSS/style.css"> </head><body>&…

Zookeeper的系统架构

先看一张图&#xff1a; ZooKeeper 的架构图中我们需要了解和掌握的主要有&#xff1a; 1&#xff1a; ZooKeeper分为服务器端&#xff08;Server&#xff09; 和客户端&#xff08;Client&#xff09;&#xff0c;客户端可以连接到整个ZooKeeper服务的任意服务器上&#xff…

Flink on Kubernetes (flink-operator) 部署Flink

flink on k8s 官网 https://nightlies.apache.org/flink/flink-kubernetes-operator-docs-release-1.1/docs/try-flink-kubernetes-operator/quick-start/ 我的部署脚本和官网不一样&#xff0c;有些地方官网不够详细 部署k8s集群 注意&#xff0c;按照默认配置至少有两台wo…