PCRE库&正则表达式匹配

PCRE(Perl Compatible Regular Expressions即:perl语言兼容正则表达式)是一个用C语言编写的正则表达式函数库,由菲利普.海泽(Philip Hazel)编写。被广泛使用在许多开源软件之中,最著名的莫过于Apache HTTP服务器和PHP脚本语言、R脚本语言,此外,正如从其名字所能看到的,PCRE也是perl语言的缺省正则库。

转载整理至:

  1. http://www.pcre.org/

  2. https://blog.csdn.net/shenwansangz/article/details/49763727

PCRE正则表达式语法

转载至:https://www.cnblogs.com/MonkeyF/p/3493009.html

字符描述
\ 将下一个字符标记为一个特殊字符,或一个原义字符,或一个向后引用,或一个八进制转义符。例如,”\n”匹配一个换行符。
^匹配输入字符串的开始位置。
$匹配输入字符串的结束为止。
*匹配前面的子表达式零或多次,等价于{0,}
+ 匹配前面的子表达式一次或多次,等价于{1,}
? 匹配前面的子表达式零次或一次,等价于{0,1}
? 当该字符紧跟在任何一个其他限制符(*,+,?,{n},{n,},{n,m})后面时,匹配模式是非贪婪的。非贪婪模式尽可能少地匹配所搜索的字符串,而默认的贪婪模式则尽可能多地匹配所搜索的字符串。例如,对于字符串”oooo”,”o+?”将匹配单个”o”,而”o+”将匹配所有的”o”。
{n} n是一个非负整数,匹配确定的n次。
{n,} n是一个非负整数,至少匹配n次。
{n,m} m和n均为非负整数,其中n<=m,最少匹配n次且最多匹配m次。
. 匹配除”\n”之外的任何单个字符。要匹配包括”\n”在内的任何字符,请使用像”[.\n]”的模式
(pattern) 匹配pattern并获取这一匹配。
(?:pattern) 匹配pattern但不获取匹配结果。这在使用“或”字符(|)来组合一个模式的各个部分是很有用的。例如:’industry|industries’就可以用’industr(?:y|ies)’代替
(?=pattern)正向预查,在任何匹配pattern的字符串开始处匹配查找字符串。例如:”Windows(?=95|98|NT|2000)”能匹配”Windows2000”中的”Windows”,但不能匹配”Windows3.1”中的”Windows”。
(?!pattern) 负向预查,在任何不匹配pattern的字符串开始处匹配查找字符串。例如:”Windows(?!95|98|NT|2000)”能匹配”Windows3.1”中的”Windows”,但不能匹配”Windows2000”中的”Windows”。
x|y 匹配x或y。
[xyz] 字符集合,匹配所包含的任何一个字符。
[^xyz] 负值字符集合,匹配未包含的任意字符。
[a-z] 字符范围,匹配指定范围内的任意字符。
[^a-z] 负值字符范围,匹配任何不在指定范围内的任意字符。
\b 匹配一个单词边界,也就是单词和空格间的位置。
\B 匹配非单词边界。
\cx 匹配由x指明的控制字符。X的值必须为A-Z或a-z之间
\d 匹配一个数字字符。等价于[0-9]
\D 匹配一个非数字字符。等价于[^0-9]
\f 匹配一个换页符。等价于\x0c和\cL
\n 匹配一个换行符。等价于\x0a和\cJ
\r 匹配一个回车符。等价于\x0d和\cM
\s 匹配任何空白字符,包括空格、制表符、换页符等。
\S 匹配任何非空白符。
\t 匹配一个制表符
\w 匹配包括下划线的任何单词字符。等价于[a-zA-Z0-9_]
\W 匹配任何非单词字符。
\xn 匹配n,其中n为十六进制转义值。例如”\x41”匹配”A”。
\num 匹配num,其中num是一个正整数。对所获取的匹配的引用。例如:”(.)\1”

PCRE API简介

全面的pcre api简介http://www.pcre.org/original/doc/html/或者man一下。

pcre_compile

#include <pcre.h>
pcre *pcre_compile(const char *pattern, int options, const char **errptr, int *erroffset, const unsigned char *tableptr); 
pcre *pcre_compile2(const char *pattern, int options, int *errorcodeptr, const char **errptr, int *erroffset, const unsigned char *tableptr);

功能:将一个正则表达式编译成一个内部表示,在匹配多个字符串时,可以加速匹配。其同pcre_compile2功能一样只是缺少一个参数errorcodeptr

参数:

pattern    正则表达式

options     为0,或者其他参数选项

errorcodeptr    存放出错码

errptr       出错消息

erroffset  出错位置

tableptr   指向一个字符数组的指针,可以设置为空NULL

pcre_exec

#include <pcre.h>
int pcre_exec(const pcre *code, const pcre_extra *extra, const char *subject, int length, int startoffset, int options, int *ovector, int ovecsize); 

功能:用来检查某个字符串是否与指定的正则表达式匹配

参数:

code, 输入参数,用pcre_compile编译好的正则表达结构的指针

extra, 输入参数,用来向pcre_exec传一些额外的数据信息的结构的指针

subject, 输入参数,要被用来匹配的字符串

length, 输入参数, 要被用来匹配的字符串的指针

startoffset, 输入参数,用来指定subject从什么位置开始被匹配的偏移量

options, 输入参数, 用来指定匹配过程中的一些选项

ovector, 输出参数,用来返回匹配位置偏移量的数组

ovecsize, 输入参数, 用来返回匹配位置偏移量的数组的最大大小

返回值:匹配成功返回非负数,匹配返回负数

pcre_study

#include <pcre.h>
pcre_extra *pcre_study(const pcre *code, int options, const char **errptr); 

功能:对编译的模式进行学习,提取可以加速匹配过程的信息。

参数:

code      已编译的模式

options    选项

errptr     出错消息

pcre_free_study

#include <pcre.h>
void pcre_free_study(pcre_extra *extra);

pcre_free

void (*pcre_free)(void *); 

使用PCRE例子

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pcre.h>

#define OVECCOUNT 30    /* should be a multiple of 3 */
#define EBUFLEN 128            
#define BUFLEN 1024

int main()
{
      pcre *reCM, *reUN, *reTC, *reCDMA; 
      const char *error;
      int erroffset;
      int ovector[OVECCOUNT];
      int rcCM, rcUN, rcTC, rcCDMA, i; 
/*        
      常用号段前三位
      中国移动CM:134.135.136.137.138.139.150.151.152.157.158.159.187.188 ,147(数据卡)
      中国联通UN:130.131.132.155.156.185.186 
      中国电信TC:133.153.180.189 
      CDMA :133,153
*/
      char src[22];  
      char pattern_CM[] = "^1(3[4-9]|5[012789]|8[78])\\d{8}$";      //正则表达式
      char pattern_UN[] = "^1(3[0-2]|5[56]|8[56])\\d{8}$";
      char pattern_TC[] = "^18[09]\\d{8}$";
      char pattern_CDMA[] = "^1[35]3\\d{8}$";
      
      printf("Please input your telephone number \n");
      scanf("%s", src);
      printf("String : %s\n", src);
      printf("Pattern_CM: \"%s\"\n", pattern_CM);
      printf("Pattern_UN: \"%s\"\n", pattern_UN);
      printf("Pattern_TC: \"%s\"\n", pattern_TC);
      printf("Pattern_CDMA: \"%s\"\n", pattern_CDMA);
       
      reCM = pcre_compile(pattern_CM, 0, &error, &erroffset, NULL);  //将正则表达式编译成pcre内部表示结构
      reUN = pcre_compile(pattern_UN, 0, &error, &erroffset, NULL);
      reTC = pcre_compile(pattern_TC, 0, &error, &erroffset, NULL);
      reCDMA = pcre_compile(pattern_CDMA, 0, &error, &erroffset, NULL);
        
      if (reCM==NULL && reUN==NULL && reTC==NULL && reCDMA==NULL) {
       printf("PCRE compilation telephone failed at offset %d: %s\n", erroffset,  error);
        return 1;        
      }

      rcCM = pcre_exec(reCM, NULL, src, strlen(src), 0, 0, ovector, OVECCOUNT);  //匹配pcre编译好的模式,成功返回正数,失败返回负数
      rcUN = pcre_exec(reUN, NULL, src, strlen(src), 0, 0, ovector, OVECCOUNT);
      rcTC = pcre_exec(reTC, NULL, src, strlen(src), 0, 0, ovector, OVECCOUNT);
      rcCDMA = pcre_exec(reCDMA, NULL, src, strlen(src), 0, 0, ovector, OVECCOUNT);
       
      if (rcCM<0 && rcUN<0 && rcTC<0 && rcCDMA<0) {      //若没匹配返回错误信息
       if (rcCM==PCRE_ERROR_NOMATCH && rcUN==PCRE_ERROR_NOMATCH &&
       rcTC==PCRE_ERROR_NOMATCH && rcTC==PCRE_ERROR_NOMATCH) {
       printf("Sorry, no match ...\n");        
        }
        else {
         printf("Matching error %d\n", rcCM);
         printf("Matching error %d\n", rcUN);
         printf("Matching error %d\n", rcTC);
         printf("Matching error %d\n", rcCDMA);
        }   
        
        free(reCM);
        free(reUN);
        free(reTC);
        free(reCDMA);
          
        return 1;
      }

      printf("\nOK, has matched ...\n\n");  //匹配成功把对应的正则表达式和号码打印出来

      if (rcCM > 0) {
       printf("Pattern_CM: \"%s\"\n", pattern_CM);
        printf("String : %s\n", src);
      }

      if (rcUN > 0) {
       printf("Pattern_UN: \"%s\"\n", pattern_UN);  
        printf("String : %s\n", src);    
      }

      if (rcTC > 0) {
       printf("Pattern_TC: \"%s\"\n", pattern_TC);
        printf("String : %s\n", src);
      }
       
      if (rcCDMA > 0) {
       printf("Pattern_CDMA: \"%s\"\n", pattern_CDMA);   
        printf("String : %s\n", src);
      }

      free(reCM);        //释放内存
      free(reUN);
      free(reTC);
      free(reCDMA);
        
      return 0;
}

发表评论

电子邮件地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据