zoukankan      html  css  js  c++  java
  • 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
    ",errbuf);
        }
    
        err = regexec(&reg,bematch,nm,pmatch,0);
    
        if(err == REG_NOMATCH){
            printf("no match
    ");
            exit(-1);
    
        }else if(err){
            regerror(err,&reg,errbuf,sizeof(errbuf));
            printf("err:%s
    ",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,'',sizeof(match));
                memcpy(match,bematch+pmatch[i].rm_so,len);
                printf("%s
    ",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
    ", src);
        printf ("Pattern: "%s"
    ", 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
    ", 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 ...
    ");
            else
                printf ("Matching error %d
    ", rc);
            pcre_free (re);
            return 1;
        }
        printf ("
    OK, has matched ...
    
    ");   //没有出错,已经匹配
        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
    ", i, substring_length, substring_start);
        }
        pcre_free (re);             // 编译正则表达式re 释放内存
        return 0;
    }

    编译

    gcc -g -o example2 example2.c -lpcre

    运行

    image

  • 相关阅读:
    合并、媒体查询
    混入、命名空间(less)、继承
    函数(内置函数 和 自定义函数)
    运算、单位、转义、颜色
    选择器嵌套、伪类嵌套、属性嵌套(只在Sass中)
    注释、变量、插值、作用域
    二路归并排序java实现
    堆排序Java实现
    和为S的连续正数序列——牛客网(剑指offer)
    transient 与 volatile 笔记
  • 原文地址:https://www.cnblogs.com/274914765qq/p/4574367.html
Copyright © 2011-2022 走看看