Chinaunix首页 | 论坛 | 博客
  • 博客访问: 384127
  • 博文数量: 80
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 1767
  • 用 户 组: 普通用户
  • 注册时间: 2013-01-24 16:18
个人简介

为啥不能追求自己的爱好一辈子呢

文章分类

全部博文(80)

文章存档

2017年(1)

2015年(2)

2014年(18)

2013年(59)

分类: LINUX

2014-01-17 10:48:46

    今天偶然的一次看到了某个人写的grep的代码,里面用了regex的代码,这个是linux系统库里面默认提供的
就稍微的研究了一下,有兴趣的同学可以通过man regex看。

   这里就简单的列出来相关的api

点击(此处)折叠或打开

  1. #include <sys/types.h>
  2. #include <regex.h>
  3. int regcomp(regex_t *preg, const char *regex, int cflags);
  4. int regexec(const regex_t *preg, const char *string, size_t nmatch,regmatch_t pmatch[], int eflags);
  5. void regfree(regex_t *preg)
大体就这三个api,regcomp 这个函数是吧一个正则表达式,转变成一个regex_t结构的值,应该是库可以识别的,regexec是执行
具体的匹配。

下面列出来主要的参数,

   regex_t *preg          这个是根据regex匹配规则由库生成的。所以我们只需要定义变量,把地址传入。
   const char *regex   这个是我们的匹配规则 
   cflags                        这个是参数 有很多下面之列出两个。
   REG_EXTENDED     表示适用Extended Regular Expressio
n
   REG_NOSUB            只会返回匹配与否,不会把匹配的具体细节表示出来。


regexec 是执行具体的匹配,其中的参数如下:
   preg                         这个是regcmp产生的正则结构
   string                      这个是要匹配的字符串
   nmatch                    一般这个表示pmatch
的个数。
   pmatch                    如果没有指定REG_NOSUB,表示要返回详细信息,就是每一个匹配的子字符串
                                    他的结构如下
                                       typedef struct {
                                             regoff_t rm_so;   //这个表示匹配的偏移量,起始位置
                                             regoff_t rm_eo;   //表示匹配的偏移量的末尾
                                          } regmatch_t;


  eflags                           我的例子中没用到                               
  
    注意这里的nmatch,和pmatch并不是吧所有的匹配都找出来的意思,只是在意个匹配中可能有group,
其中pmatch【0】会保存整个匹配的位置,pmatch[1...2]会保存group匹配。group的概念其实就是匹配
的字串加上小括号。
下面的例子很容易说明。

点击(此处)折叠或打开

  1. #include
    #include
    #include
    #include
    int main()
    {
          char *haa = "a very simple simple simple string";
             char       *regex = "([a-z]+)[ \t]([a-z]+)";
        regex_t comment;
        size_t nmatch;
        regmatch_t regmatch[100];
        regcomp(&comment, regex, REG_EXTENDED|REG_NEWLINE);
        int j = regexec(&comment,haa,sizeof(regmatch)/sizeof(regmatch_t),regmatch,0);
        if(j != 0)
            return -1;
  2.     //输出匹配字串
        for(int i = 0; i< 100 && regmatch[i].rm_so!= -1;i++)
        {   
            std::string str;
            str.assign(haa+regmatch[i].rm_so, regmatch[i].rm_eo - regmatch[i].rm_so);
            printf("%s\n",str.c_str());
        }  
  3.     regfree(&comment);
        return 0;


结果为:

点击(此处)折叠或打开

  1. a very
  2. a
  3. very
如上所示,  他只匹配了第一个 a very  ,但是因为有(),group也会匹配到子串里面。,如果想要全部找到,需要在外层循环匹配啦。
下面写个有点小错误的,但是确实表现了reg。

点击(此处)折叠或打开

  1. #include<sys/types.h>
  2. #include<regex.h>
  3. #include<string>
  4. #include<stdio.h>
  5. int main()
  6. {
  7.       char *haa = "a very simple simple simple string";
  8.          char *regex = "([a-z]+)[ \t]([a-z]+)";
  9.     regex_t comment;
  10.     size_t nmatch;
  11.     regmatch_t regmatch[100];
  12.     regcomp(&comment, regex, REG_EXTENDED|REG_NEWLINE);
  13.     while(1)
  14.     {
  15.         int j = regexec(&comment,haa,sizeof(regmatch)/sizeof(regmatch_t),regmatch,0);
  16.         if(j != 0)
  17.             break;
  18.         for(int i = 0; i< 100 && regmatch[i]. -1;i++)
  19.         {
  20.             std::string str;
  21.             str.assign(haa+regmatch[i].rm_so, regmatch[i].rm_eo - regmatch[i].rm_so);
  22.             printf("%s\n",str.c_str());
  23.         }

  24.         if(regmatch[0].rm_so != -1)
  25.             haa+= regmatch[0].rm_eo;
  26.     }
  27.     regfree(&comment);
  28.     return 0;
  29. }
附上结果

点击(此处)折叠或打开

  1. a very
  2. a
  3. very
  4. simple simple
  5. simple
  6. simple
  7. simple string
  8. simple
  9. string
其实 very simple 也算是啦。






阅读(5981) | 评论(0) | 转发(0) |
2

上一篇:c++ 右移

下一篇:shell 重定向的妙用

给主人留下些什么吧!~~