C語言使用正則表達式


一、簡介

一個好的程序員是會使用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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM