正则表达式
正则表达式是用来描述某种规则的字符串的表达式。
脱离了具体语言的一些规则,但是现在大多数程序设计语言都实现了
支持正则表达式:
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;
®
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(®,IP_REG, REG_EXTENDED | REG_ICASE);//编译正则表达式
if(ret==0)
{
ret=regexec(®,string, 3, pmatch, 0);//匹配正则表达式所描述的模式
if(ret==REG_NOMATCH)
{
regerror(ret,®,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 , ®, buf, 512);
printf("error : %s\n", buf);
}
regfree(®);//释放空间
}
int main()
{
Is_IPString(IP_STR);
return 0;
}