一、简介

一个好的程序员是会使用DB和Regular Expression的程序员,可见两者是多么重要。正则表达式是能极大地提高工作效率的工具,使用过Linux下各种具备RE特性的工具的人一定对此深有感触。很多语言都支持RE,用的最多的当然是脚本,其中以perl最盛。不过,用C语言来用RE不是很多见,但是有时候也很有用,我最近也是看到别人说道这个,所以搜了一些资料加上自己的体会来说一说RE在C语言里的应用。C语言本身不具备RE特性,但是有很多库,在Linux下你可以很方便的使用regex.h提供的库。

 

二、API

 

三、实例

示例1:example1.c

#include<stdio.h>                                                                                                        
#include<sys/types.h>
#include<regex.h>
#include<memory.h>
#include<stdlib.h>

int main(){

    char *bematch = "hhhericchd@gmail.com";
    char *pattern = "h{3,10}(.*)@.{5}.(.*)";
    char errbuf[1024];
    char match[100];
    regex_t reg;
    int err,nm = 10;
    regmatch_t pmatch[nm];

    if(regcomp(&reg,pattern,REG_EXTENDED) < 0){
        regerror(err,&reg,errbuf,sizeof(errbuf));
        printf("err:%s\n",errbuf);
    }

    err = regexec(&reg,bematch,nm,pmatch,0);

    if(err == REG_NOMATCH){
        printf("no match\n");
        exit(-1);

    }else if(err){
        regerror(err,&reg,errbuf,sizeof(errbuf));
        printf("err:%s\n",errbuf);
        exit(-1);
    }

    for(int i=0;i<10 && pmatch[i].rm_so!=-1;i++){
        int len = pmatch[i].rm_eo-pmatch[i].rm_so;
        if(len){
            memset(match,'\0',sizeof(match));
            memcpy(match,bematch+pmatch[i].rm_so,len);
            printf("%s\n",match);
        }
    }
    return 0;
}

编译

gcc -g -o example1 example1.c --std=c99

运行

image

 

示例2:example2.c

#define PCRE_STATIC             // 静态库编译选项
#include <stdio.h>
#include <string.h>
#include <pcre.h>
#define OVECCOUNT 30
#define EBUFLEN 128
#define BUFLEN 1024

int main ()
{
    pcre *re;
    const char *error;
    int erroffset;
    int ovector[OVECCOUNT];
    int rc, i;
    char src[] = "111 <title>Hello World</title> 222";  // 要被用来匹配的字符串
    char pattern[] = "<title>(.*)</(tit)le>";   // 将要被编译的字符串形式的正则表达式
    printf ("String : %s\n", src);
    printf ("Pattern: \"%s\"\n", pattern);
    re = pcre_compile (pattern, // pattern, 输入参数,将要被编译的字符串形式的正则表达式
                       0,       // options, 输入参数,用来指定编译时的一些选项
                       &error,  // errptr, 输出参数,用来输出错误信息
                       &erroffset,  // erroffset, 输出参数,pattern中出错位置的偏移量
                       NULL);   // tableptr, 输入参数,用来指定字符表,一般情况用NULL
    // 返回值:被编译好的正则表达式的pcre内部表示结构
    if (re == NULL)
    {
        //如果编译失败,返回错误信息
        printf ("PCRE compilation failed at offset %d: %s\n", erroffset, error);
        return 1;
    }
    rc = pcre_exec (re,         // code, 输入参数,用pcre_compile编译好的正则表达结构的指针
                    NULL,       // extra, 输入参数,用来向pcre_exec传一些额外的数据信息的结构的指针
                    src,        // subject, 输入参数,要被用来匹配的字符串
                    strlen (src),   // length, 输入参数,要被用来匹配的字符串的指针
                    0,          // startoffset, 输入参数,用来指定subject从什么位置开始被匹配的偏移量
                    0,          // options, 输入参数,用来指定匹配过程中的一些选项
                    ovector,    // ovector, 输出参数,用来返回匹配位置偏移量的数组
                    OVECCOUNT); // ovecsize, 输入参数, 用来返回匹配位置偏移量的数组的最大大小
    // 返回值:匹配成功返回非负数,没有匹配返回负数
    if (rc < 0)
    {
        //如果没有匹配,返回错误信息
        if (rc == PCRE_ERROR_NOMATCH)
            printf ("Sorry, no match ...\n");
        else
            printf ("Matching error %d\n", rc);
        pcre_free (re);
        return 1;
    }
    printf ("\nOK, has matched ...\n\n");   //没有出错,已经匹配
    for (i = 0; i < rc; i++)
    {
        //分别取出捕获分组 $0整个正则公式 $1第一个()
        char *substring_start = src + ovector[2 * i];
        int substring_length = ovector[2 * i + 1] - ovector[2 * i];
        printf ("$-: %d,%d,%s\n", i, substring_length, substring_start);
    }
    pcre_free (re);             // 编译正则表达式re 释放内存
    return 0;
}

编译

gcc -g -o example2 example2.c -lpcre

运行

image

posted on 2015-06-13 23:32  红孩儿你好  阅读(24695)  评论(0编辑  收藏  举报