posix 正则库程序
使用的是posix 正则库,参考:
http://see.xidian.edu.cn/cpp/html/1428.html
执行匹配的时:
gcc myreg.c
ip.pat 内容:
ip
.*[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+
ip.txt 内容:
192.168.1.1
测试:
./a.out ip.pat ip.txt
下面是myreg.c源代码
/* myreg.c */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <regex.h>
#include <unistd.h>
#define MAX 256
/* 存放匹配位置信息的结构体 */
typedef struct placemsg_t
{
int start[MAX]; //匹配的开始位置
int end[MAX]; //匹配的结束位置
int count; //匹配次数
} placemsg;
#define TIMES 100
#define MAX_PATTERN_LEN 8192
/**
* @brief 实现一个字符十六进制到十进制的转换
*
* @param c 需要转换的字符
*
* @return 错误返回 -1
*/
static int hex2dec(char c)
{
switch (c)
{
case '0' ... '9':
return c - '0';
case 'a' ... 'f':
return c - 'a' + 10;
case 'A' ... 'F':
return c - 'A' + 10;
default:
fprintf(stderr, "hex2dec: bad value!\n");
return -1;
}
}
/*
* @brief 把正则的\xHH格式的十六进制形式用字符形式代替
* takes a string with \xHH escapes and returns one with the characters they stand for
*
* @param s \xHH形式的正则表达式
*
* @return 返回字符形式的正则表达式
*/
static char *pre_process(char *s)
{
char *result = malloc(strlen(s) + 1);
int sindex = 0, rindex = 0;
while( sindex < strlen(s) )
{
if( sindex + 3 < strlen(s) &&
s[sindex] == '\\' && s[sindex+1] == 'x' &&
isxdigit(s[sindex + 2]) && isxdigit(s[sindex + 3]) )
{
/* carefully remember to call tolower here... */
result[rindex] = tolower( hex2dec(s[sindex + 2])*16 +
hex2dec(s[sindex + 3] ) );
sindex += 3; /* 4 total */
}
else
result[rindex] = tolower(s[sindex]);
sindex++;
rindex++;
}
result[rindex] = '\0';
return result;
}
//判断是不是注释
// Returns true if the line (from a pattern file) is a comment
static int is_comment(char* line)
{
unsigned int i;
// blank lines are comments
if(strlen(line) == 0) return 1;
// lines starting with # are comments
if(line[0] == '#') return 1;
// lines with only whitespace are comments
for(i = 0; i < strlen(line); i++)
{
if(!isspace(line[i]))
{
return 0;
}
}
return 1;
}
//获得.pat中的协议名称
static char *get_protocol_name (char *line, char **patname)
{
unsigned int i, j;
char *name = *patname;
j = 0;
for (i=0; i<strlen(line); i++)
{
if(!isspace (line[i]))
{
name[j] = line[i];
j++;
}
else
{
break;
}
}
return name;
}
//找到最后的slash(/)
int last_mark (char *str, char mark)
{
int site = 0;
int count = 0;
int size = strlen(str);
while (site <= size)
{
if (str[site++] == mark)
{
count = site;
}
}
return count;
}
//找到第一个dot(.)
int first_mark (char *str, char mark, int num)
{
int count = num;
while (1)
{
if (str[count++] == mark)
{
break;
}
}
return count;
}
/* 从文件全名中把文件名提取出来,没有后缀 */
int substr (char *srcstr, char **decstr, int lastslash, int firstdot)
{
int i = 0;
//int ls = lastslash;
char *str = *decstr;
//printf("last=%d,first=%d\n", lastslash, firstdot);
//printf("size=%d\n", firstdot-lastslash);
int size = firstdot-lastslash-1;
for (i=0; i<size; i++)
{
//str[i] = srcstr[ls++];
//printf("...%c...\n",srcstr[lastslash]);
str[i] = srcstr[lastslash++];
}
}
//得到文件名
int basename(char *file, char **name)
{
int lastnum = last_mark (file, '/');
int firstnum = first_mark (file, '.', lastnum);
substr (file, name, lastnum, firstnum);
//printf ("name = %s\n", name);
return 0;
}
/**
* @brief 以下是pcre匹配的相关函数原型:
* int regcomp(regex_t *preg, const char *regex, int cflags);
* cflags: REG_EXTENDED | REG_NEWLINE;
* REG_EXTENDED 支持扩展的正则
* REG_NEWLINE; 包括换行
* int regexec(const regex_t *preg, const char *string, size_t nmatch, regmatch_t pmatch[], int eflags);
* eflags = REG_NOTBOL | REG_NOTEOL;
* REG_NOTBOL 行结尾
* REG_NOTEOL 文件结尾
* size_t regerror(int errcode, const regex_t *preg, char *errbuf, size_t errbuf_size);
* void regfree(regex_t *preg);
* @param regexp 正则表达式模式文件
* @param file_path 要进行匹配的文件路径
*
* @return 匹配信息结构体
*/
struct placemsg_t reg(char *regexpfile, char *file_path)
{
regex_t preg;
struct placemsg_t placeinfo;
regmatch_t pmatch[MAX] = {};
size_t nmatch = MAX;
size_t length;
char errbuf[MAX] = {};
size_t errbuf_size;
int res;
int errcode;
FILE *fp;
int fd;
long sitestart;
long siteend;
long filesize;
char *string;
int patternlen, i;
int flag = 1;
FILE * fp2;
char * line = NULL;
size_t len = 0;
ssize_t size;
char *filename = (char*)malloc(256);
//提取.pat文件名
basename(regexpfile, &filename);
//提取.pat中的正则表达式
//printf ("1regexpfile=%s\n", regexpfile);
fp2 = fopen (regexpfile, "r");
if (fp2 == NULL)
{
perror("fopen");
}
flag = 1;
while ((size= getline(&line, &len, fp2)) != -1)
{
line[strlen(line)-1] = '\0';
//printf ("line=%s\n", line);
//判断是否是注释
if(is_comment(line))
{
printf("is_comment\n");
continue;
}
else if((strstr(line, filename) == 0) && flag)
{
//printf("..........strcpy...........\n");
flag = 0;
continue;
}
else if(flag)
{
continue;
}
else if (flag == 0)
{
printf("正则表达式是:%s\n", line);
break;
}
}
fclose(fp2);
fp2 = NULL;
free(filename);
printf ("2line=%s\n", line);
//转换正则表达式为字符
char *regexpstr = pre_process(line); /* do \xHH escapes */
printf("regexpstr=%s\n", regexpstr);
if(line)
{
free(line);
}
printf("file_path=%s\n", file_path);
fp = fopen(file_path, "r");
if (fp == NULL)
{
perror("fopen");
}
fseek(fp, 0, SEEK_SET);
sitestart = ftell(fp);
fseek(fp, 0, SEEK_END);
siteend = ftell(fp);
filesize = siteend - sitestart;
printf("filezize=%d\n", filesize);
string = (char*) malloc(sizeof(char)*filesize+4);
memset(string, 0, filesize+4);
fclose(fp);
fp = NULL;
fd = open(file_path, O_RDONLY);
if (fd == -1)
{
perror ("open");
}
res = read(fd, string, filesize);
if (res == -1)
{
perror ("read");
}
close(fd);
printf("res=%d,string=%s\n", res, string);
printf("begin regcomp.........\n");
int cflags = REG_EXTENDED | REG_NEWLINE;
//int cflags = REG_EXTENDED;
//int cflags = 0;
//编译正则表达式
res = regcomp (&preg, regexpstr, cflags);
printf("begin regexec.........\n");
//int eflags = REG_NOTBOL | REG_NOTEOL;
int eflags = REG_NOTEOL;
//int eflags = 0;
int place[5];
int start_front=0;
int start_now=0;
int end_front=0;
int end_now=0;
int temp = 0;
char *p = string;
i = 0;
while (1)
{
res = regexec (&preg, p, nmatch, pmatch, eflags);
if (res == 0)
{
printf("...........match..........\n");
start_now = pmatch[0].rm_so;
end_now = pmatch[0].rm_eo;
temp = end_now - start_now;
//printf("temp=%d\n", temp);
start_now = end_front + start_now;
//printf("start_now=%d\n", start_now);
end_now = start_now + temp;
//printf("end_now=%d\n", end_now);
start_front = start_now;
end_front = end_now;
//printf("start place=%d\n", pmatch[0].rm_so);
//printf("end place=%d\n", pmatch[0].rm_eo);
//printf("start place=%d\n", start_front);
//printf("end place=%d\n", end_front);
placeinfo.start[i] = start_front;
placeinfo.end[i] = end_front;
p += pmatch[0].rm_eo;
if(!*p)
{
i++;
break;
}
}
else
{
printf("no match\n");
break;
}
i++;
}
placeinfo.count = i;
//printf(".....i=%d\n", i);
length = regerror (res, &preg, errbuf, errbuf_size);
regfree(&preg);
free(string);
free(regexpstr);
//printf("over\n");
return placeinfo;
}
int main (int argc, char **argv)
{
//char *regexp = "r.t";
char *regexpfile = argv[1];
printf("regexpfile=%s\n", regexpfile);
//char *file_path = "t.txt";
char *file_path = argv[2];
struct placemsg_t placeinfo;
placeinfo = reg(regexpfile, file_path);
int size = placeinfo.count;
printf(".....show....\n");
int i = 0;
for (i=0; i<size; i++)
{
printf ("start[%d]=%d\n", i, placeinfo.start[i]);
printf ("end[%d]=%d\n", i, placeinfo.end[i]);
}
return 0;
}
posix 正则库程序的更多相关文章
- 使用POSIX正则库匹配一行中多个结果
正则匹配与正则表达式是什么东西我就不说了,在这里说下POSIX这个c语言正则库在对字符串进行正则匹配时取出多个结果的问题. 首先简单说明下POSIX正则库的几个函数和使用方法 第一个函数:int re ...
- [02]APUE:POSIX 正则库(#include <regex.h>)
正则匹配流程: 声明一个 regex_t 类型的变量(结构体) regcomp 函数会将“正则匹配条件”写入此结构体,并编译成特定的二进制格式(加快匹配速度) 声明一个 regmatch_t 类型的变 ...
- C正则库做DNS域名验证时的性能对比
C正则库做DNS域名验证时的性能对比 本文对C的正则库regex和pcre在做域名验证的场景下做评测. 验证DNS域名的正则表达式为: "^[0-9a-zA-Z_-]+(\\.[0-9a ...
- posix线程库1
posix线程库重要的程度不言而喻,这些天学习这个,参考 https://www.ibm.com/developerworks/cn/linux/thread/posix_thread1/ 首先先 ...
- 【归纳】正则表达式及Python中的正则库
正则表达式 正则表达式30分钟入门教程 runoob正则式教程 正则表达式练习题集(附答案) 元字符\b代表单词的分界处,在英文中指空格,标点符号或换行 例子:\bhi\b可以用来匹配hi这个单词,且 ...
- Linux posix线程库总结
由于历史原因,2.5.x以前的linux对pthreads没有提供内核级的支持,所以在linux上的pthreads实现只能采用n:1的方式,也称为库实现. 线程的实现,经历了如下发展阶段: Linu ...
- 从零开始攻略PHP(5)——字符串操作与POSIX正则
一.字符串操作 1.字符串的格式化 1.1 干掉空格 trim()函数可以除去字符串开始位置和结束位置的空格,并将结果字符串返回. ltrim()函数可以除去字符串开始位置的空格. rtrim()函数 ...
- PCRE正则库的使用
使用pcre编写C或C++程序,然后编译. 对于C程序,编译命令为:gcc -I/usr/local/include/pcre -L/usr/local/lib/pcre -lpcre file.c ...
- PHP学习(5)——字符串操作与POSIX正则
一.字符串操作 1.字符串的格式化 1.1 干掉空格 trim()函数可以除去字符串开始位置和结束位置的空格,并将结果字符串返回. ltrim()函数可以除去字符串开始位置的空格. rtrim()函数 ...
随机推荐
- 【BZOJ4373】算术天才⑨与等差数列 线段树+set
[BZOJ4373]算术天才⑨与等差数列 Description 算术天才⑨非常喜欢和等差数列玩耍.有一天,他给了你一个长度为n的序列,其中第i个数为a[i].他想考考你,每次他会给出询问l,r,k, ...
- EasyPlayerPro Windows流媒体播放器(RTSP/RTMP/HTTP/HLS/File/TCP/RTP/UDP都能播)发布啦
EasyPlayerPro简介 EasyPlayerPro是一款全功能的流媒体播放器,支持RTSP.RTMP.HTTP.HLS.UDP.RTP.File等多种流媒体协议播放.支持本地文件播放,支持本地 ...
- poj 2151Check the difficulty of problems<概率DP>
链接:http://poj.org/problem?id=2151 题意:一场比赛有 T 支队伍,共 M 道题, 给出每支队伍能解出各题的概率~ 求 :冠军至少做出 N 题且每队至少做出一题的概率~ ...
- 九度OJ 1158:买房子 (基础题)
时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:1801 解决:1096 题目描述: 某程序员开始工作,年薪N万,他希望在中关村公馆买一套60平米的房子,现在价格是200万,假设房子价格以每 ...
- HTML5+ Android打包证书
HBuilder默认App云端打包默认使用的是DCloud公用证书,其信息如下: MD5: 59:20:1C:F6:58:92:02:CB:2C:DA:B2:67:52:47:21:12 SHA1:B ...
- HNOI2016
本蒟蒻表示终于$AC$了$HNOI2016$的六道毒瘤题... 高兴! 附上各个题的题解: $DAY1$: $T1$: BZOJ4537: [Hnoi2016]最小公倍数 $T2$: BZOJ4538 ...
- Codeforces - 828C String Reconstruction —— 并查集find()函数
题目链接:http://codeforces.com/contest/828/problem/C C. String Reconstruction time limit per test 2 seco ...
- apace搭建站点
Listen 127.0.0.1:3310<VirtualHost *:3306> ServerName 127.0.0.1:3306 DocumentRoot "F:/Baid ...
- laravel基础课程---5、路由复习(路由作用)
laravel基础课程---5.路由复习(路由作用) 一.总结 一句话总结: 有利于百度收录,及SEO优化 1.路由书写 (D:\laravel\yzmedu\yzm2\routes\web.php) ...
- Python: Neural Networks
这是用Python实现的Neural Networks, 基于Python 2.7.9, numpy, matplotlib. 代码来源于斯坦福大学的课程: http://cs231n.github. ...