日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

Linux C 支持正則表達(dá)式的字符串替換函數(shù)

 jijo 2008-09-11








[root@localhost src]# cat a.c
/**
* Linux C 支持正則表達(dá)式的字符串替換函數(shù)
*
* Author: cnscn@163.com
* Homepage: www.cnscn.org  歡迎您到cns家園來,有好吃的招待喲
* Date:   2007-03-08 17:41
*
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>

//regex
#include <regex.h>


//cns_reg函數(shù)的返回類型
typedef struct _reg_rtn_struct
{
   int rtn;       //成功與否標(biāo)志0 成功, 1失敗
   int pstart;    //匹配到的子串開始位移
   int pend;      //匹配到的子串尾部位移
} reg_rtn_struct;


/**
*
* 正則表達(dá)式查找函數(shù)
*/
reg_rtn_struct cns_reg(const char *str,  const char *pattern)
{
    reg_rtn_struct reg_rtn_struct_var;

    int          z;            //status
    int          pos;          //配置處的位置
    int          cflags = REG_EXTENDED;   //compile flags
    regex_t      reg;          //compiled regular expression
    char         ebuf[128];    //error buffer
    bzero(ebuf, sizeof(ebuf));
    regmatch_t   pm[10];       //pattern matches 0-9
    bzero(pm, sizeof(pm));
    const size_t nmatch = 10;  //The size of array pm[]

    //編譯正則表達(dá)式
    /**
     *
     * @param const char*  pattern         將要被編譯的正則表達(dá)式
     * @param regex_t*     reg             用來保存編譯結(jié)果
     * @param int          cflags          決定正則表達(dá)式將如何被處理的細(xì)節(jié)
     *
     * @return  success    int        0    并把編譯結(jié)果填充到reg結(jié)構(gòu)中
     *          fail       int        非0
     *
     */


    z = regcomp(&reg, (const char*)pattern, cflags);

    if(z)   //此處為 if(z != 0), 因?yàn)镃語言里0永遠(yuǎn)為非(False), 任何非0值都為真(True)
    {
       regerror(z, &reg, ebuf, sizeof(ebuf));
       perror("reg1");
       fprintf(stderr, "%s: pattern '%s'\n", ebuf, pattern);
       reg_rtn_struct_var.rtn    = 1;
       reg_rtn_struct_var.pstart = -1;
       reg_rtn_struct_var.pend   = -1;

       regfree(&reg);
       return reg_rtn_struct_var;
    }

    /**
     *
     * reg     指向編譯后的正則表達(dá)式
     * str     指向?qū)⒁M(jìn)行匹配的字符串
     * pm      str字符串中可能有多處和正則表達(dá)式相匹配, pm數(shù)組用來保存這些位置
     * nmacth  指定pm數(shù)組最多可以存放的匹配位置數(shù)
     *
     * @return 函數(shù)匹配成功后,str+pm[0].rm_so到str+pm[0].rm_eo是第一個(gè)匹配的子串
     *                           str+pm[1].rm_so到str+pm[1].rm_eo是第二個(gè)匹配的子串
     *                           ....
     */
    z = regexec(&reg, str, nmatch, pm, 0);

    //沒有找到匹配數(shù)據(jù)
    if(z == REG_NOMATCH)
    {
       reg_rtn_struct_var.rtn    = 1;
       reg_rtn_struct_var.pstart = -1;
       reg_rtn_struct_var.pend   = -1;

       regfree(&reg);
       return reg_rtn_struct_var;
    }
    else if(z)  //if(z !=0)
    {
       perror("reg3");
       regerror(z, &reg, ebuf, sizeof(ebuf));
       fprintf(stderr, "%s: regcomp('%s')\n", ebuf, str);

       reg_rtn_struct_var.rtn    = 1;
       reg_rtn_struct_var.pstart = -1;
       reg_rtn_struct_var.pend   = -1;
       regfree(&reg);

       return reg_rtn_struct_var;
    }

    /*列出匹配的位置*/
    if(pm[0].rm_so != -1)
    {
       reg_rtn_struct_var.rtn    = 0;
       reg_rtn_struct_var.pstart = pm[0].rm_so;
       reg_rtn_struct_var.pend   = pm[0].rm_eo;
    }

    regfree(&reg);
    return reg_rtn_struct_var;
}


/*
* 正則表達(dá)式替換函數(shù)
*/
char *cns_str_ereplace(char *src, const char *pattern, const char *newsubstr)
{
    //如果pattern和newsubstr串相等,則直接返回
    if(!strcmp(pattern, newsubstr))   //if(strcmp(pattern, newsubstr)==0)
       return src;

    //定義cns_reg的返回類型結(jié)構(gòu)變量
    reg_rtn_struct  reg_rtn_struct_var;
    int rtn    = 0;   //reg_rtn_struct_var.rtn
    int pstart = 0;   //reg_rtn_struct_var.pstart
    int pend   = 0;   //reg_rtn_struct_var.pend


    //把源串預(yù)dest
    char *dest=src;  //替換后生成的串指針
    char *pstr=src;  //當(dāng)找到串時(shí),pstr就指向子串后面的地址從而標(biāo)識(shí)下一個(gè)要查找的源串

    //用于malloc的臨時(shí)內(nèi)存區(qū)
    char *tmp;
    char *new_tmp_str=dest;

    int new_tmp_str_len=0;  //new_tmp_str相對(duì)于dest地址開始處的長度


    //開始循環(huán)替換src串中符合pattern的子串為newstr
    while(!rtn)
    {
        reg_rtn_struct_var=cns_reg(new_tmp_str, pattern);

        rtn    = reg_rtn_struct_var.rtn;
        pstart = reg_rtn_struct_var.pstart;
        pend   = reg_rtn_struct_var.pend;

        if(!rtn)
        {
            //分配新的空間: strlen(newstr):新串長  pend-pstart:舊串長
            tmp=(char*)calloc(sizeof(char), strlen(dest)+strlen(newsubstr)-(pend-pstart)+1 );

            //把src內(nèi)的前new_tmp_str_len+pstart個(gè)內(nèi)存空間的數(shù)據(jù),拷貝到arr
            strncpy(tmp, dest, new_tmp_str_len+pstart);

            //標(biāo)識(shí)串結(jié)束
            tmp[new_tmp_str_len+pstart]='\0';

            //連接arr和newstr, 即把newstr附在arr尾部, 從而組成新串(或說字符數(shù)組)arr
            strcat(tmp, newsubstr);

            //把src中 從oldstr子串位置后的部分和arr連接在一起,組成新串a(chǎn)rr
            strcat(tmp, new_tmp_str+pend);

            //把用malloc分配的內(nèi)存,復(fù)制給指針dest
            dest = strdup(tmp);

            //釋放malloc分配的內(nèi)存空間
            free(tmp);

            new_tmp_str_len = new_tmp_str_len + pstart + strlen(newsubstr);
            new_tmp_str=dest+new_tmp_str_len;
        }
    }

    return dest;
}


int main()
{
  //測試正則表達(dá)式
  char str[]="1love2love3love4love5love6love!";

  reg_rtn_struct reg_rtn_struct_var;

  char *newstr=cns_str_ereplace(str,".?.?ve","..");
  puts(newstr);

  return 0;
}

[root@localhost src]# gcc -g a.c -o a && ./a
_such_.._you_love_you_love_you_sir!
_such_.._you_.._you_love_you_sir!
_such_.._you_.._you_.._you_sir!
_such_.._you_.._you_.._you_sir!









    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多