嵌入式Linux系统编程 — 4.7 regcomp、regexec、regfree正则表达式函数

目录

1 为什么需要正则表达式

2 正则表达式简介

3 正则表达式规则

4 regcomp、regexec、regfree函数

4.1 函数介绍

4.2 URL格式案例


1 为什么需要正则表达式

在许多的应用程序当中, 有这样的应用场景: 给定一个字符串,检查该字符串是否符合某种条件或规则、或者从给定的字符串中找出符合某种条件或规则的子字符串, 将匹配到的字符串提取出来。这种需要在很多的应用程序当中是存在的:

  • 例如,很多应用程序都有这种校验功能,譬如检验用户输入的账号或密码是否符合它们定义的规则,如果不符合规则通常会提示用户按照正确的规则输入用户名或密码。
  • 譬如给定一个字符串,在程序当中判断该字符串是否是一个 IP 地址, 对于实现这个功能, 大家可能首先想到的是,使用万能的 for 循环, 当然,笔者首先肯定的是, 使用 for 循环自然是可以解决这个问题, 但是在程序代码处理上会比较麻烦,有兴趣的朋友可以自己试一下。

对于这些需求,其实只需要通过一个正则表达式就可以搞定了, 下一小节开始将向大家介绍正则表达式。

2 正则表达式简介

正则表达式又称为规则表达式(Regular Expression),正则表达式通常被用来检索、替换那些符合某个模式(规则)的字符串,正则表达式描述了一种字符串的匹配模式(pattern),可以用来检查一个给定的字符串中是否含有某种子字符串、将匹配的字符串替换或者从某个字符串中取出符合某个条件的子字符串。

在 Linux 系统下运行命令的时候,使用过?或*通配符来查找硬盘上的文件或者文本中的某个字符串, ?通配符匹配 0 个或 1 个字符,而*通配符匹配 0 个或多个字符,譬如"data?.txt"这样的匹配模式可以将下列文件查找出来:

        data.dat
        data1.dat
        data2.dat
        datax.dat
        dataN.dat

许多程序设计语言都支持正则表达式。譬如,在 Perl 中就内建了一个功能强大的正则表达式引擎、Python提供了内置模块 re 用于处理正则表达式, 正则表达式这个概念最初是由 Unix 中的工具软件(例如 sed 和grep)普及开的。同样,在 C 语言函数库中也提供了用于处理正则表达式的接口供程序员使用。

3 正则表达式规则

正则表达式的匹配语法和规则是用于指定搜索模式的字符串,它们由普通字符(如字母和数字)和特殊字符组成。特殊字符有着不同的用途,例如匹配模式、重复次数、字符类等。下面是一些常用的正则表达式元素及其匹配规则:

普通字符:直接匹配自身,如 a 匹配字符 'a'。

特殊字符

  • .:匹配任意单个字符(除了换行符)。
  • ^:匹配输入字符串的开始位置。
  • $:匹配输入字符串的结束位置。
  • |:逻辑或操作符,匹配两个模式中的一个。
  • []:字符集,匹配括号内的任意字符,如 [abc] 匹配 'a'、'b' 或 'c'。
  • ():分组,将多个规则组合成一个单元,也可以用于捕获匹配的子字符串。

量词:指定元素出现的次数。

  • *:匹配前面的子模式零次或多次。
  • +:匹配前面的子模式一次或多次。
  • ?:匹配前面的子模式零次或一次。
  • {n}:匹配确定的 n 次数。
  • {n,}:至少匹配 n 次。
  • {n,m}:最少匹配 n 次且最多 m 次。

转义特殊字符:使用 \ 对特殊字符进行转义,使其作为普通字符匹配,如 \. 匹配字符 '.'。

字符类

  • \d:匹配任何数字,等同于 [0-9]
  • \w:匹配任何字母数字字符,包括下划线,等同于 [A-Za-z0-9_]
  • \s:匹配任何空白字符(空格、制表符、换行符等)。

否定字符集:使用 ^ 放在 [ 后面来表示否定字符集,如 [^abc] 匹配除了 'a'、'b'、'c' 之外的任何字符。

懒惰(非贪婪)匹配:在量词后面加上 ? 使其变为懒惰模式,尽可能少地匹配字符,如 .*? 尽可能少地匹配任何字符。

断言

  • \b:匹配单词边界。
  • (?=...):正向先行断言,匹配...前面的位置。
  • (?!...):负向先行断言,匹配除了...之外的前面的位置。

回溯引用:使用 \1\2、... 来引用之前通过分组捕获的匹配。

模式修饰符

  • i:不区分大小写。
  • g:全局搜索。
  • m:多行匹配。

4 regcomp、regexec、regfree函数

regcompregexecregfree 是正则表达式库中的三个核心函数,用于编译、匹配、释放正则表达式。

4.1 函数介绍

regcomp() 函数:编译正则表达式字符串,生成一个正则表达式对象。原型:

#include <regex.h>int regcomp(regex_t *preg, const char *pattern, int cflags);
  • preg:指向 regex_t 结构的指针,用于存储编译后的正则表达式。
  • pattern:要编译的正则表达式字符串。
  • cflags:编译时的选项标志,常用的有 REG_EXTENDED(扩展正则表达式)和 REG_ICASE(不区分大小写的匹配)。

regexec() 函数:使用编译后的正则表达式对象匹配目标字符串。

int regexec(const regex_t *preg, const char *string, size_t nmatch, regmatch_t pmatch[], int eflags);
  • preg:指向编译后的正则表达式的 regex_t 结构。
  • string:要匹配的字符串。
  • nmatch:匹配结果数组的大小,0 表示不存储匹配结果。
  • pmatch:指向 regmatch_t 数组的指针,用于存储每个匹配结果的起始和结束位置。数组的大小至少为 nmatch
  • eflags:执行匹配时的选项标志,如 REG_NOTBOL^ 不匹配字符串的开始)和 REG_NOTEOL$ 不匹配字符串的结束)。

regfree() 函数:释放 regcomp() 函数分配的内存资源。

void regfree(regex_t *preg);
  • preg:指向 regex_t 结构的指针,该结构是之前通过 regcomp() 函数编译得到的。

4.2 URL格式案例

^((ht|f)tps?)://[-A-Za-z0-9_]+(\.[-A-Za-z0-9_]+)+([-A-Za-z0-9_.,@?^=%&:/~+#]*[-A-Za-z0-9_@?^=%&/~+#])?$

上面的正则表达式用于匹配大多数的URL格式。下面是对正则表达式各部分的解释:

  • ^:匹配字符串的开始。
  • ((ht|f)tps?):匹配 "http" 或 "https",问号表示前面的字符 "s" 是可选的。
  • ://:匹配 "://",这是URL协议部分和域名部分的分隔符。
  • [-A-Za-z0-9_]+:匹配域名的第一个部分,允许字母、数字、连字符和下划线,+ 表示一个或多个。
  • (\.[-A-Za-z0-9_]+)+:匹配域名的后续部分,可以有多个,格式为点后跟一个或多个允许的字符。
  • ([-A-Za-z0-9_.,@?^=%&:/~+#]*:匹配URL的路径部分的开始,允许字母、数字、点、逗号和其他一些URL中常见的特殊字符,* 表示零个或多个。
  • [-A-Za-z0-9_@?^=%&/~+#]):正则表达式的最后部分,匹配路径的结束,允许的字符与上面相同,但这里只允许一个字符,因为整个路径部分已经通过前面的 * 匹配了任意长度。
  • ?:使路径部分成为可选。
  • $:匹配字符串的结束。

这个正则表达式可以匹配以下类型的URL:

  • http://example.com
  • https://www.example.com
  • http://example.com/path/to/resource
  • https://example.com?query=string

下面的程序,使用正则表达式库来验证用户输入的URL字符串是否符合特定的格式。

#include <stdio.h>
#include <stdlib.h>
#include <regex.h>
#include <string.h> // 引入字符串处理函数#define MAX_URL_LENGTH 1024int main() {char url[MAX_URL_LENGTH]; // 修正后的正则表达式,注意转义序列const char *pattern = "^((ht|f)tps?)://[-A-Za-z0-9_]+(\\.[-A-Za-z0-9_]+)+([-A-Za-z0-9_.,@?^=%&:/~+#]*[-A-Za-z0-9_@?^=%&/~+#])?$";regex_t regex;int ret;// 请求用户输入URLprintf("请输入URL: ");fgets(url, MAX_URL_LENGTH, stdin); // 使用fgets读取一行输入// 去除fgets读取的末尾换行符size_t len = strlen(url);if(len > 0 && url[len - 1] == '\n') {url[len - 1] = '\0';}// 编译正则表达式ret = regcomp(&regex, pattern, REG_EXTENDED);if (ret) {fprintf(stderr, "Error compiling regex\n");exit(1);}// 执行匹配ret = regexec(&regex, url, 0, NULL, 0);if (!ret) {printf("'%s' 是一个有效的URL。\n", url);} else {printf("'%s' 不是一个有效的URL。\n", url);}// 释放正则表达式分配的资源regfree(&regex);return 0;
}

首先程序提示用户输入URL,使用fgets函数读取用户输入后,程序去除末尾的换行符。接着、编译一个预定义的正则表达式,并用它来检查输入的URL。如果URL匹配正则表达式模式,则认为它是有效的,并打印相应消息;否则,打印无效消息。最后,程序释放与正则表达式相关的资源。程序运行结果如下:

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

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

相关文章

分布式锁及其实现与应用场景

分布式锁及其实现与应用场景 分布式锁是一种用于在分布式系统中协调多个进程或线程对共享资源进行访问的机制。它的主要目的是确保在同一时间只有一个进程或线程可以访问特定资源&#xff0c;从而避免数据竞争和不一致问题。分布式锁通常用于集群环境中&#xff0c;例如微服务…

Rpc服务的提供方(Rpcprovider)的调用流程

首先&#xff0c;服务的提供方&#xff0c;会通过rpcprovider向rpc服务方注册rpc服务对象和服务方法&#xff0c; 那么&#xff0c;我们通过protobuf提供的抽象层的service和method&#xff0c;将服务对象和它所对应的服务方法记录在map表中&#xff0c; 当它启动以后&#xff…

Qt之饼图(Pie Graph)

[TOC](Qt之饼图(Pie Graph)) 饼图名为Pie Graph&#xff0c;用于显示一个数据系列中各项的大小与各项总和的比例。本文基于QtCharts实现饼图的显示。 1.实现过程 1.1环境配置 &#xff08;1&#xff09;首先想要使用QtCharts模块&#xff0c;需要在安装qt时选择勾选安装QtCha…

【名企专访】|格行自有格行的骄傲,格行骄傲在哪?格行随身wifi火爆出圈的真实内幕!

最近刷视频在一个随身wifi的帖子下边看到&#xff0c;有个网友这样回复&#xff1a;“随身wifi行业真的该整治了&#xff0c;到处是跑路的&#xff0c;夸大宣传的&#xff0c;本来在线上买就是图个方便&#xff0c;现在搞得不敢买。本来利民的产品&#xff0c;被搞得乌烟瘴气&a…

甄选范文“论云上自动化运维及其应用”,软考高级论文,系统架构设计师论文

论文真题 云上自动化运维是传统IT运维和DevOps的延伸,通过云原生架构实现运维的再进化。云上自动化运维可以有效帮助企业降低IT运维成本,提升系统的灵活度,以及系统的交付速度,增强系统的可靠性,构建更加安全、可信、开放的业务平台。 请围绕“云上自动化运维及其应用”…

windows 10 安装tcping 使用教程

1 官网下载:tcping下载 2 复制tcping 到win10系统目录C:\Windows\System32 3 tcping 网址测试,可以指定端口 4 tcping 测试端口联通 5 tcping http模式

【原创图解 算法leetcode 146】实现一个LRU缓存淘汰策略策略的数据结构

1 概念 LRU是Least Recently Used的缩写&#xff0c;即最近最少使用&#xff0c;是一种常见的缓存淘汰算法。 其核心思想为&#xff1a;当内存达到上限时&#xff0c;淘汰最久未被访问的缓存。 2 LeetCode LeetCode: 146. LRU缓存 3 实现 通过上面LRU的淘汰策略可知&#…

【多维动态规划】Leetcode 221. 最大正方形【中等】

最大正方形 在一个由 ‘0’ 和 ‘1’ 组成的二维矩阵内&#xff0c;找到只包含 ‘1’ 的最大正方形&#xff0c;并返回其面积。 示例 1&#xff1a; 输入&#xff1a;matrix [[“1”,“0”,“1”,“0”,“0”],[“1”,“0”,“1”,“1”,“1”],[“1”,“1”,“1”,“1”,“…

程序中的Reduce(CPU和GPU)

前提 最近在看Reduce&#xff08;归约&#xff09;的相关知识和代码&#xff0c;做个总结。这里默认大家已经明白了Reduce的基础概念。 Reduce 根据参考链接一&#xff0c;Recude常见的划分方法有两种&#xff1a; 相邻配对&#xff1a;元素和它们相邻的元素配对 交错配对…

【Mybatis】Mybatis初识-通过源码学习执行流程

文章目录 1.Mybatis核心组件1.1 SqlSession1.2 SqlSessionFactory1.3 Mapper1.4 MappedStatement1.5 Executor 2. Mybatis各组件之间关系3. 构建SqlSessionFactory3.1 从XML文件中构建3.2 不使用XML构建SqlSessionFactory 4. 如何从SqlSessionFactory获取SqlSession5.获取Mappe…

【AMBA】APB总线的个人学习记录(一):理论知识

精通APB (Advanced Peripheral Bus) 总线设计通常意味着你不仅理解其基础概念&#xff0c;而且能够在实际的硬件设计中灵活运用APB总线&#xff0c;解决复杂问题&#xff0c;并优化设计。以下是一些关键点&#xff0c;当你掌握这些方面时&#xff0c;可以说你对APB总线设计有了…

《昇思25天学习打卡营第6天|onereal》

Vision Transformer&#xff08;ViT&#xff09;简介 近些年&#xff0c;随着基于自注意&#xff08;Self-Attention&#xff09;结构的模型的发展&#xff0c;特别是Transformer模型的提出&#xff0c;极大地促进了自然语言处理模型的发展。由于Transformers的计算效率和可扩…

[OtterCTF 2018]Bit 4 Bit

我们已经发现这个恶意软件是一个勒索软件。查找攻击者的比特币地址。** 勒索软件总喜欢把勒索标志丢在显眼的地方&#xff0c;所以搜索桌面的记录 volatility.exe -f .\OtterCTF.vmem --profileWin7SP1x64 filescan | Select-String “Desktop” 0x000000007d660500 2 0 -W-r-…

数据库系统概论(第5版教材)

第一章 绪论 1、数据(Data)是描述事物的符号记录&#xff1b; 2、数据库系统的构成&#xff1a;数据库 、数据库管理系统&#xff08;及其开发工具&#xff09; 、应用程序和数据库管理员&#xff1b; 3、数据库是长期存储在计算机内、有组织、可共享的大量数据的集合&…

带上作弊器,我不得起飞

前言 过去,我们对人工智能既期待又害怕.人类的惰性希望人工智能可以帮助大家从大部分繁重的工作中解放出来,但又害怕它失控. 智能系统的好处 工作方面 自动化与效率提升&#xff1a;可以自动执行许多重复性和低技能的任务&#xff0c;如制造业中的装配、数据输入和办公室的客户…

原子变量原理剖析

一、原子操作 原子操作保证指令以原子的方式执行&#xff0c;执行过程不被打断。先看一个实例&#xff0c;如下所示&#xff0c;如果thread_func_a和thread_func_b同时运行&#xff0c;执行完成后&#xff0c;i的值是多少&#xff1f; // test.c static int i 0;void thread…

多表执行嵌套查询,减少笛卡尔积,防止内存溢出

问题&#xff1a;当涉及四个表的查询时&#xff0c;会产生大量的笛卡尔积导致内存溢出。 解决办法 &#xff1a;可以使用嵌套查询将多表的联合查询拆分为单个表的查询&#xff0c;使用resultmap中的association&#xff08;适合一对一&#xff09; 或 collection&#xff08;一…

医院消防设施设备管理系统

医院为人员密集场所&#xff0c;且多为各类病患及其陪护人员&#xff0c;一旦发生火灾&#xff0c;人员疏散逃生困难&#xff0c;容易造成较严重的生命与财产损失。为规范医院的消防设施设备管理&#xff0c;通过凡尔码系统对医院消防设施设备进行信息化管理&#xff0c;提高医…

MapReduce学习

目录 7.3 MapReduce工作流程 7.3.1 工作流程概述 7.3.2 MapReduce各个执行阶段 7.3.3 Shuffle过程详解 1. Shuffle过程简介&#xff08;过程分为Map端的操作和Reduce端的操作&#xff09; 2、Map端的Shuffle过程&#xff1a; 3、在Reduce端的Shuffle过程 7.4 实例分析&am…

使用supportFragmentManager管理多个fragment切换

android studio创建的项目就没有一个简单点的框架&#xff0c;生成的代码都是繁琐而复杂&#xff0c;并且不实用。 国内的页面一般都是TAB页面的比较多&#xff0c;老外更喜欢侧边菜单。 如果我们使用一个activity来创建程序&#xff0c;来用占位符管理多个fragment切换&…