使用的是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 正则库程序的更多相关文章

  1. 使用POSIX正则库匹配一行中多个结果

    正则匹配与正则表达式是什么东西我就不说了,在这里说下POSIX这个c语言正则库在对字符串进行正则匹配时取出多个结果的问题. 首先简单说明下POSIX正则库的几个函数和使用方法 第一个函数:int re ...

  2. [02]APUE:POSIX 正则库(#include <regex.h>)

    正则匹配流程: 声明一个 regex_t 类型的变量(结构体) regcomp 函数会将“正则匹配条件”写入此结构体,并编译成特定的二进制格式(加快匹配速度) 声明一个 regmatch_t 类型的变 ...

  3. C正则库做DNS域名验证时的性能对比

    C正则库做DNS域名验证时的性能对比   本文对C的正则库regex和pcre在做域名验证的场景下做评测. 验证DNS域名的正则表达式为: "^[0-9a-zA-Z_-]+(\\.[0-9a ...

  4. posix线程库1

    posix线程库重要的程度不言而喻,这些天学习这个,参考 https://www.ibm.com/developerworks/cn/linux/thread/posix_thread1/   首先先 ...

  5. 【归纳】正则表达式及Python中的正则库

    正则表达式 正则表达式30分钟入门教程 runoob正则式教程 正则表达式练习题集(附答案) 元字符\b代表单词的分界处,在英文中指空格,标点符号或换行 例子:\bhi\b可以用来匹配hi这个单词,且 ...

  6. Linux posix线程库总结

    由于历史原因,2.5.x以前的linux对pthreads没有提供内核级的支持,所以在linux上的pthreads实现只能采用n:1的方式,也称为库实现. 线程的实现,经历了如下发展阶段: Linu ...

  7. 从零开始攻略PHP(5)——字符串操作与POSIX正则

    一.字符串操作 1.字符串的格式化 1.1 干掉空格 trim()函数可以除去字符串开始位置和结束位置的空格,并将结果字符串返回. ltrim()函数可以除去字符串开始位置的空格. rtrim()函数 ...

  8. PCRE正则库的使用

    使用pcre编写C或C++程序,然后编译. 对于C程序,编译命令为:gcc -I/usr/local/include/pcre -L/usr/local/lib/pcre -lpcre file.c ...

  9. PHP学习(5)——字符串操作与POSIX正则

    一.字符串操作 1.字符串的格式化 1.1 干掉空格 trim()函数可以除去字符串开始位置和结束位置的空格,并将结果字符串返回. ltrim()函数可以除去字符串开始位置的空格. rtrim()函数 ...

随机推荐

  1. 【BZOJ4373】算术天才⑨与等差数列 线段树+set

    [BZOJ4373]算术天才⑨与等差数列 Description 算术天才⑨非常喜欢和等差数列玩耍.有一天,他给了你一个长度为n的序列,其中第i个数为a[i].他想考考你,每次他会给出询问l,r,k, ...

  2. EasyPlayerPro Windows流媒体播放器(RTSP/RTMP/HTTP/HLS/File/TCP/RTP/UDP都能播)发布啦

    EasyPlayerPro简介 EasyPlayerPro是一款全功能的流媒体播放器,支持RTSP.RTMP.HTTP.HLS.UDP.RTP.File等多种流媒体协议播放.支持本地文件播放,支持本地 ...

  3. poj 2151Check the difficulty of problems<概率DP>

    链接:http://poj.org/problem?id=2151 题意:一场比赛有 T 支队伍,共 M 道题, 给出每支队伍能解出各题的概率~  求 :冠军至少做出 N 题且每队至少做出一题的概率~ ...

  4. 九度OJ 1158:买房子 (基础题)

    时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:1801 解决:1096 题目描述: 某程序员开始工作,年薪N万,他希望在中关村公馆买一套60平米的房子,现在价格是200万,假设房子价格以每 ...

  5. HTML5+ Android打包证书

    HBuilder默认App云端打包默认使用的是DCloud公用证书,其信息如下: MD5: 59:20:1C:F6:58:92:02:CB:2C:DA:B2:67:52:47:21:12 SHA1:B ...

  6. HNOI2016

    本蒟蒻表示终于$AC$了$HNOI2016$的六道毒瘤题... 高兴! 附上各个题的题解: $DAY1$: $T1$: BZOJ4537: [Hnoi2016]最小公倍数 $T2$: BZOJ4538 ...

  7. Codeforces - 828C String Reconstruction —— 并查集find()函数

    题目链接:http://codeforces.com/contest/828/problem/C C. String Reconstruction time limit per test 2 seco ...

  8. apace搭建站点

    Listen 127.0.0.1:3310<VirtualHost *:3306> ServerName 127.0.0.1:3306 DocumentRoot "F:/Baid ...

  9. laravel基础课程---5、路由复习(路由作用)

    laravel基础课程---5.路由复习(路由作用) 一.总结 一句话总结: 有利于百度收录,及SEO优化 1.路由书写 (D:\laravel\yzmedu\yzm2\routes\web.php) ...

  10. Python: Neural Networks

    这是用Python实现的Neural Networks, 基于Python 2.7.9, numpy, matplotlib. 代码来源于斯坦福大学的课程: http://cs231n.github. ...