正则表达式以及在C语言中调用相关函数

正则表达式

正则表达式是用来描述某种规则的字符串的表达式。
脱离了具体语言的一些规则,但是现在大多数程序设计语言都实现了
支持正则表达式:
C语言
python
C++
C#
java

但是每种语言实现正则表达式的规则略有不同。

正则表达式的规则
如:

		十进制数字字符串
		[0-9]+ 

正则表达式也叫做 匹配模式(pattern),它是由一组特定含义的字符串组成,通常用于匹配和替换文本。

正则表达式中的字符,分为两种:

	(1) 普通字符: 只代表自己本身的字符
			0 ~ 9  a~z  A~Z 
			
(2) 元字符: 有特定含义(不代表自己)的字符 
			+ *  

正则表达式中的元字符:

.	匹配任意单个字符 

[]	字符组。

匹配任意一个十六进制的字符。
[0123456789abcdefABCDEF] 
[]仅匹配括号内的一个字符。

'-'[]内用于链接ASCII连续的字符  
匹配任意一个十六进制的字符。
[0-9a-fA-F]  

匹配单个字符

[^]	排除字符组。匹配单个字符,匹配除[]内意外的所有单个字符。 
				如: 
					非十进制数字字符 
						[^0-9]
						
			\d	digtial 
				匹配单个十进制数字字符 
				\d <=> [0-9]
				
			\D 	匹配单个非十进制数字字符 
				\D <=> [^0-9]
				
			\w	word 
				匹配单个单词中能够出现的字符
				字母、数字、_ 
				\w <=> [0-9a-zA-Z_]  
				
			\W	非字母、数字、_ 中的单个字符
				\W <=> [^0-9a-zA-Z_]
					
			\s	space 
				匹配单个空白符 
				\s <=> [\f\n\r\t\v]
			
			\S 	匹配单个非空白符 
				\S <=> [^\f\n\r\t\v]  
				
				例子:  
					[a-c^0-9] 
					匹配单个的 a-c 、0-9^

匹配多个字符

+	匹配一个或多个先前字符 或 模式
09+ ==	09
		099
		0999
		09999
		........ 

*	匹配0个或多个先前字符 或 模式 
?	匹配0个或1个先前的字符 或 模式 

{数字}	匹配固定数目的字符 或 模式
88[0-9]{3}== 
			88[0-9][0-9][0-9]

{最小数目, 最大数目}	     匹配至少"最下数目",到"最大数目"的先前字符或模式 
8{1, 3} ==8
		 88
		888 
	
{最小数目, }     匹配至少"最小数目",上不封顶 的先前字符 或 模式。		

() 	作为一个整体,子模式 	
(abc){1,3}==abc 
			abcabc
			abcabcabc 

(|)	二选一 				

转义元字符
\元字符 => 元字符它就不是元字符,就是这个字符本身含义。

					\. 代表一个普通字符'.' 
					\* 代表一个普通字符'*'
					\+ 代表一个普通字符'+'
					\? 代表一个普通字符'?' 
					...... 

C语言对应的正则表达式函数

regcomp: 用来编译正则表达式
编译好的正则表达式用类型 regex_t 来表示。

#include <sys/types.h>
#include <regex.h>
int regcomp(regex_t * preg, const char *regex, int cflags);

				@preg : 指向的地址空间,用来保存编译好了的正则表达式的
					a、regex_t reg;
						&reg  
					b、regex_t * preg = (regex_t *)malloc(sizeof(*preg));
						preg 
			
				@regex :指向原始的待编译的正则表达式 
				
				@cflags: 有如下标志,用位域实现  '|'
					REG_EXTENDED : 用扩展的正则表达式的语法来进行编译 
					REG_ICASE : ignore case 忽略大小写 
					REG_NOSUB : 不包含子模式
					
					如: 既要使用扩展的正则表达式语法 也要忽略大小写 
						=> 	REG_EXTENDED | REG_ICASE 
				
				返回值: 
					成功返回0 
					失败返回一个错误码,该错误码需要调用 regerror去解析。

regexec : 用来匹配正则表达式所描述的模式
匹配的结果用 regmatch_t 来描述,返回的是母串中匹配到的下标的范围。[起始下标 ,结束下标)

 int regexec(const regex_t *preg, const char *string, size_t nmatch,regmatch_t pmatch[], int eflags); 
				@preg : 指向编译好了的正则表达式 	   
				@string : 原始的待匹配的母字符串。带查找的字符串
				@nmatch : 正则表达式中有多少个模式 
					总模式 + 子模式 
					
				@pmatch : 模式匹配信息 数组 
					数组元素个数 : nmatch 
					一个模式匹配 就需要用一个regmatch_t结构体变量
					......
					总共有多少个模式,就需要有多少个regmatch_t
					
				@eflags : 标志是否匹配行首或行尾 
					一般是填0 
				返回值: 
					成功(匹配到了)返回0 
						如果一个待匹配的字符串中,匹配成功多个模式,
						如何去查看匹配到的信息(结果)? 
							循环 访问 regmatch_t pmatch[ nmatch ] 数组中的元素。 
					如果失败返回 REG_NOMATCH

regerror :用来把regcomp / regexec 执行返回的错误码,转换成相应的无措字符串信息。

 size_t regerror(int errcode, const regex_t *preg, char *errbuf,size_t errbuf_size);
						   
				@errcode : 错误码。由regcomp / regexec返回的值 
				@preg : 编译好了的正则表达式 
				
				@errbuf: 指向一个存储空间,这个存储空间是用来保存出错信息。
				@errbuf_size : 表示errbuf的大小。 
				
				返回值:  
					返回填充到errbuf中的错误提示字符串的长度。

regfree :用来释放preg指向的空间

void regfree(regex_t *preg);

写一个函数,判断一个字符串是否为一个IP字符串?

int Is_IPString(char * p)
	{
	}
	待查找的字符串(母串): 
		abc192.168.31.67abcdefgee 
		
		总模式: 192.168.31.67
				[3,16) 
				
		子模式: 192 
				[3,6) 
				
		子模式: 67 
				[14,16)

代码如下:

#include<stdio.h>
#include<sys/types.h>
#include<regex.h>
#include <string.h>

#define IP_REG "([0-9]{1,3})\\.[0-9]{1,3}\\.[0-9]{1,3}\\.([0-9]{1,3})"
#define IP_STR "abc192.168.1.1qqqq"

void Is_IPString(char* string)
{
	
	int ret;//保存错误码
	regex_t reg;//保存编译好的正则表达式
	regmatch_t pmatch[3];//保存匹配到的模式

	char buf[512];//保存出错信息
	memset(buf,0,512);

	ret=regcomp(&reg,IP_REG, REG_EXTENDED | REG_ICASE);//编译正则表达式
	if(ret==0)
	{
		ret=regexec(&reg,string, 3, pmatch, 0);//匹配正则表达式所描述的模式
		if(ret==REG_NOMATCH)
		{
			 regerror(ret,&reg,buf,512);//返回错误码
			 printf("error :%s\n",buf);
		}
		else
		{
			int i,j;
			for(i  = 0; i < 3; i++)
			{
				printf("[%d, %d)\n", pmatch[i].rm_so , pmatch[i].rm_eo);//取pmatch下标
				for(j = pmatch[i].rm_so ; j < pmatch[i].rm_eo ; j++)
				{
					printf("%c", string[j]);
				}
				printf("\n");
			}
		}
	}
		else
		{
			regerror(ret , &reg, buf, 512); 
			printf("error : %s\n",  buf);
		}
			regfree(&reg);//释放空间
	}

int main()
{
	Is_IPString(IP_STR);
	return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ChampLixxx

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值