C之正则表达式

C之正则表达式

C不直接支持正则表达式,但是有部分函数是支持的,比如sscanf

关于sscanf

这儿有个练手的程序:ref

#include <stdio.h>
 
int main()
{
    //例1:从<sip:tom@172.18.1.133>中提取tom
    const char* url = "<sip:tom@172.18.1.133>";
    char uri[10] = {0};
    sscanf(url, "%*[^:]:%[^@]", uri);
    printf("uri:%s\n", uri);
 
    //例2:从iios/12DDWDFF@122中提取 12DDWDFF
    const char* s = "iios/12DDWDFF@122";
    char buf[20];
    sscanf(s, "%*[^/]/%[^@]", buf);
    printf("buf:%s\n", buf);
 
    int k;
    sscanf( "AAA123BBB456" , "%*[^0-9]%i" , &k) ;
    printf("%d\n",k);
    return 0;
}

需要说明的是:

  1. 表达式中%表示选择 ,%后面的是条件,就像正常使用中的%s
  2. %xx% 两个%(及以上)是会段错误的,因为第一个识别结束后就不会再识别
  3. %*是过滤字符,而且该函数字符匹配一旦错误则会直接退出,不会再扫描后面的字符,因此字符过滤十分常用。
  4. 例如%x Y %x中的Y,是分隔符,可与字符串中的符号匹配
  5. %i,是将数字字符转换成int型数据

ref1
ref2
不难发现,该字符匹配处理规则还是正则表达式不是完全的相同的。因此C语言中实现正则表达式的匹配还是很有必要的

C-正则表达式

以下函数的组合使用,就是为了正确的在C语言中使用正则表达式。
POSIX regex functions:

regcomp

用来编译正则表达式

int regcomp(regex_t *preg, const char *regex, int cflags);
  • @preg 保存编译好的正则表达式
  • @regex 待编译的原始正则表达式
  • @cflags 模式选择
  • @return_value 成功返回0;失败返回错误码

regexec

用来匹配正则表达式所描述的模式,匹配结果用regmatch_t来描述,返回的是在母串中匹配到的下标的范围。

int regexec(const regex_t *preg, const char *string, size_t nmatch, regmatch_t pmatch[], int eflags)
  • @preg 编译好了的正则表达式
  • @string 待匹配的原始字符串
  • @nmatch 正则表达式的模式个数(总模式+子模式)
  • @pmatch 数组名,保存匹配到的模式结果信息
  • @eflags 标志是否匹配行首或行尾
  • @return_flag 成功则返回0,失败返回REG_NOMATCH

regerror

将上面regcomp和regexec执行返回的错误码,转换成相应的错误字符串信息。

int regerror(int errcode, const regex_t *preg, char *errbuf, int errbuf_size)
  • @errcode 错误码
  • @preg 编译好的正则表达式
  • @errbuf 保存出错信息
  • @errbuf_size errbuf大小
  • @return_value 返回填充到errbuf中的错误提示字符串的长度

regfree

释放preg指向的空间

void regfree(regex_t *preg);

练手

用一个正则表达式来描述一个正确的IP字符串?
在这里插入图片描述
模式个数 = 1 + 括号个数

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <regex.h>
#define MAXSIZE 100
#define N 3 //模式 
#define REG_IP "([0-9]{1,3})\\.[0-9]{1,3}\\.[0-9]{1,3}\\.([0-9]{1,3})"

//待查找字符串:
const char * str = "abc192.168.1.250abchauhfiouh" ;

int main()
{
	regex_t* preg = (regex_t *)malloc(sizeof(regex_t));//保存编译好的正则表达式的空间
	char *errbuf1 = (char *)malloc(MAXSIZE);//保存编译出错的信息1
	char *errbuf2 = (char *)malloc(MAXSIZE);//保存编译出错的信息2

	//1.编译正则表达式
	int errorCode = regcomp(preg, REG_IP, REG_EXTENDED);//包含子模式 
	if(errorCode)
	{
		//解析错误信息
		regerror(errorCode, preg, errbuf1, MAXSIZE);
		//打印错误信息
		printf("%s\n", errbuf1); 
		return -1;    
	}
	
	//2.找总模式以及子模式
	regmatch_t pmatch[N];
	int ret = regexec(preg, str, N, pmatch, 0); 
	if(ret == REG_NOMATCH)
	{
		//解析错误信息
		regerror(ret, preg, errbuf2, MAXSIZE);
		//打印错误信息
		printf("%s\n", errbuf1); 
		return -1;	
	}

	//3.将找到的模式结果信息打印出来
	for(int i = 0; i < N; i++)
	{
		printf("[%d, %d)\n", pmatch[i].rm_so, pmatch[i].rm_eo);
	}
	for(int i = 0; i < 3; i++)
	{
		printf("[%d, %d) :", pmatch[i].rm_so, pmatch[i].rm_eo);
		int j;
		for(j = pmatch[i].rm_so; j < pmatch[i].rm_eo ; j++)
		{
			printf("%c", *(str+j));
		}
		printf("\n");	
	}

	//4.释放正则表达式的空间
	regfree(preg);
	
	return 0;

}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值