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

news2024/11/24 2:00:23

官方仓库: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 here
    let 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.coloradmin.cn/o/1566207.html

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

相关文章

LCD1602显示屏

LCD1602显示 概述 LCD1602&#xff08;Liquid Crystal Display&#xff09;是一种工业字符型液晶&#xff0c;能够同时显示 1602 即 32 字符(16列两行) 引脚说明 //电源 VSS -- GND VDD -- 5V //对比度 VO -- GND //控制线 RS -- P1.0 RW -- P1.1 E -- P1.4 //背光灯 A -- 5…

Python快速入门系列-8(Python数据分析与可视化)

第八章:Python数据分析与可视化 8.1 数据处理与清洗8.1.1 数据加载与查看8.1.2 数据清洗与处理8.1.3 数据转换与整理8.2 数据可视化工具介绍8.2.1 Matplotlib8.2.2 Seaborn8.2.3 Plotly8.3 数据挖掘与机器学习简介8.3.1 Scikit-learn8.3.2 TensorFlow总结在本章中,我们将探讨…

在Java中对SQL进行常规操作的通用方法

SQL通用方法 一、常规方法增删改查二、具体优化步骤1.准备工作2.getcon()方法&#xff0c;获取数据库连接对象3.closeAll()方法&#xff0c;关闭所有资源4.通用的增删改方法5.通用的查询方法6.动态查询语句 总结 一、常规方法增删改查 在常规方法中&#xff0c;我们在Java中对…

rocketmq的运维

1. admintool创建topic的时候 -o 的用法含义 https://rocketmq.apache.org/zh/docs/4.x/producer/03message2/ 有关orderMessageEnable和returnOrderTopicConfigToBroker的设置可以参考 https://blog.csdn.net/sdaujsj1/article/details/115741572 -c configFile通过-c命令指…

Sy6 编辑器vi的应用(+shell脚本3例子)

实验环境&#xff1a; 宿主机为win11&#xff0c;网络&#xff1a;10.255.50.5 6389 WSL2 ubuntu 目标机的OS&#xff1a;Ubuntu 内核、版本如下&#xff1a; linuxpeggy0223:/$ uname -r 5.15.146.1-microsoft-standard-WSL2 linuxpeggy0223:/$ cat /proc/version Linux vers…

MYSQL数据库:告别慢查询,优化性能大揭秘

​&#x1f308; 个人主页&#xff1a;danci_ &#x1f525; 系列专栏&#xff1a;《设计模式》《MYSQL应用》 &#x1f4aa;&#x1f3fb; 制定明确可量化的目标&#xff0c;坚持默默的做事。 MYSQL数据库&#xff1a;告别慢查询&#xff0c;优化性能大揭秘 文章目录 一、揭秘…

「每日跟读」句型公式 第2篇

「每日跟读」句型公式 第2篇 1. I’m thinking about____ 我在考虑____ I’m thinking about my future career (我正在思考我未来的职业) I’m thinking about our marriage (我在考虑我们的婚姻) I’m thinking about taking a vacation (我在考虑度一个假) I’m think…

书生·浦语大模型InternLM-Chat-1.8B 智能对话 Demo 第二期

文章目录 InternLM-Chat-1.8B 智能对话 Demo环境准备下载模型运行 InternLM-Chat-1.8B web 运行八戒 demo下载模型执行Demo InternLM-Chat-1.8B 智能对话 Demo 环境准备 在InternStudio平台中选择 10% A100(1/4) 的配置&#xff08;平台资源有限&#xff09;&#xff0c;如下图…

【微服务】——Nacos注册中心

这里写自定义目录标题 1.认识和安装Nacos2.服务注册到nacos1&#xff09;引入依赖2&#xff09;配置nacos地址3&#xff09;重启 3.服务分级存储模型3.1.给user-service配置集群3.2.同集群优先的负载均衡 4.权重配置5.环境隔离5.1.创建namespace5.2.给微服务配置namespace 6.Na…

PS从入门到精通视频各类教程整理全集,包含素材、作业等(7)

PS从入门到精通视频各类教程整理全集&#xff0c;包含素材、作业等 最新PS以及插件合集&#xff0c;可在我以往文章中找到 由于阿里云盘有分享次受限制和文件大小限制&#xff0c;今天先分享到这里&#xff0c;后续持续更新 PS敬伟01——90集等文件 https://www.alipan.com/s…

Typecho自媒体博客Spimes主题 X7.2

主题介绍 spimes主题专为博客、自媒体、资讯类的网站设计开发&#xff0c;自适应兼容手机、平板设备。一款简约新闻自媒体类的 typecho 主题&#xff0c;设计上简约、干净、精致、响应式&#xff0c;后台设置更是强大而且实用的新闻自媒体类主题。 已经更新到7.2&#xff0c;删…

优于五大先进模型,浙江大学杜震洪团队提出 GNNWLR 模型:提升成矿预测准确性

卡塔尔世界杯自 2010 年荣膺举办权&#xff0c;直至 2022 年辉煌成功举办&#xff0c;累计投入资金高达约 2,290 亿美元。相较之下&#xff0c;此前七届世界杯的总花费仅约 400 多亿美元。这场体育盛事展现出奢华无度的风采&#xff0c;归根结底源于卡塔尔这个国度的深厚底蕴。…

官宣!一文掌握2024百度CreateAI开发者大会最新议程

4月16日上午9:00&#xff0c;以“创造未来”为主题的2024百度Create AI开发者大会将在深圳国际会展中心&#xff08;宝安&#xff09;开幕。此次大会将是近十年来&#xff0c;粤港澳大湾区规格最高的AI大会&#xff0c;将聚焦炙手可热的AI话题&#xff0c;在大会主论坛、分论坛…

回溯算法|46.全排列

力扣题目链接 class Solution { public:vector<vector<int>> result;vector<int> path;void backtracking (vector<int>& nums, vector<bool>& used) {// 此时说明找到了一组if (path.size() nums.size()) {result.push_back(path);re…

阿里云数据库服务器价格表查询_一张表精准报价

阿里云数据库服务器价格表&#xff0c;优惠99元一年起&#xff0c;ECS云服务器2核2G、3M固定带宽、40G ESSD Entry云盘&#xff0c;优惠价格99元一年&#xff1b;阿里云数据库MySQL版2核2G基础系列经济版99元1年、2核4GB 227.99元1年&#xff0c;云数据库PostgreSQL、SQL Serve…

9.动态规划——4.最长公共子序列(动态规划类的算法题该如何解决?)

例题——最长公共子序列(一) 分析 设最长公共子序列 d p [ i ] [ j ] dp[i][j] dp[i][j]是 S 1 S_1 S1​的前 i i i个元素&#xff0c;是 S 2 S_2 S2​的前 j j j个元素&#xff0c;那么有&#xff1a; 若 S 1 [ i − 1 ] S 2 [ i − 1 ] S_1[i-1]S_2[i-1] S1​[i−1]S2​[…

基于深度学习的吸烟行为检测系统(网页版+YOLOv8/v7/v6/v5代码+训练数据集)

摘要&#xff1a;本文深入研究了基于深度学习的吸烟行为检测系统&#xff0c;核心采用YOLOv8并整合了YOLOv7、YOLOv6、YOLOv5算法&#xff0c;进行性能指标对比&#xff1b;详述了国内外研究现状、数据集处理、算法原理、模型构建与训练代码&#xff0c;及基于Streamlit的交互式…

某音a_bogus 流程vmp分析

声明 本文章中所有内容仅供学习交流,抓包内容、敏感网址、数据接口均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关,若有侵权,请联系我立即删除! 目标网站 仅研究。网站链接自己去找。 前言 这里a_bogus 又是个vmp。 还是个多层嵌套…

小红数组操作(结构体模拟链表详细解析)(双向链表)c/c++

题目描述: 小红拿到了一个数组&#xff0c;初始数组为空&#xff0c;她希望你实现以下两种操作&#xff1a; 1. 输入x,y&#xff0c;将x插入在元素y的右边。保证此时数组中没有元素等于x&#xff0c;且数组中存在一个y。特殊的&#xff0c;如果将x插入在数组的最左边&#xff0…

微生物群落关键种识别:一种不依赖于网络的自上而下的方法

微生物群落在促进养分循环、协助植物生长、维持人体健康等方面发挥着重要的作用。群落关键种对维持微生物群落稳定性具有重要影响&#xff0c;识别关键种一直是微生物生态学中的热点话题。识别关键种主要有两种框架&#xff1a;数据驱动的方法&#xff08;data driven method&a…