Posix正则表达式API说明

1 头文件

#include <regex.h>

2 基本方法

2.1 regcomp

  • 函数原型

    int regcomp(regex_t *preg, const char *regex, int cflags);

  • 功能

    编译正则表达式,以便regexec方法使用

  • 参数含义
    • preg

      preg是一个指向编译后的正则表达式结构的指针,p意思是pointer,reg意思是regex_t类型。

      regex_t是一个结构体数据类型,用来存放编译后的正则表达式,它的成员re_nsub用来存储正则表达式中的子正则表达式的个数,子正则表达式就是用圆括号包起来的部分表达式。

    • regex

      描述正则表达式的字符串。

    • cflags

      决定编译的类型。 可选值有:

      说明
      REG_EXTENDED 扩展的正则表达式,如果不设置则为基本的正则表达式
      REG_ICASE 不区分大小写
      REG_NOSUB 不用存储匹配后的结果。如果设置该标志位,那么在regexec将忽略nmatch和pmatch两个参数。
      REG_NEWLINE 识别换行符。
  • 返回值
    返回值 说明
    0 成功
    其他错误码 失败

2.2 regexec

  • 函数原型

    int regexec(const regex_t *preg, const char *string, size_t nmatch, regmatch_t pmatch[], int eflags);
  • 功能

    根据编译好的正则表达式,对字符串进行匹配

  • 参数含义
    • preg

      经过regcomp编译的正则表达式。

    • string

      待匹配的字符串。

    • nmatch

      匹配到的字符串的个数。

    • pmatch

      匹配到的数组。

    • eflags

      匹配的标志,可选的值有:

      说明
      REG_NOTBOL 不匹配行的开头,除非在regcomp编译时cflag设置REG_NEWLINE
      REG_NOTEOL 不匹配行的结束,除非在regcomp编译时cflag设置REG_NEWLINE
  • 返回值
    返回值 说明
    0 成功
    REG_NOTMATCH 失败

2.3 结构体regmatch_t

regmatch_t 的定义如下

typedef struct {
      regoff_t  rm_so;
      regoff_t  rm_eo;
      } regmatch_t;

其中:

如果-1==rm_so,表示没有匹配到。

如果-1!=rm_so,表示string中下一个最大子字符串的偏移量

rm_eo表示子字符串的长度。

2.4 regerror

  • 函数原型

    size_t regerror(int errcode, const regex_t *preg, char * errbuf, size_t errbuf_size);
  • 功能

    将regcomp和regexec返回的errorcode转换成错误信

  • 参数含义
    • errorcode

      错误码,由regcomp或regexec获得。

    • preg

      经过regcomp编译的正则表达式。

    • errbuf

      存储错误信息的buffer。

    • errbuf_size

      errbuf的大小。

  • 返回值

    返回errbuf存储错误信息所需要的大小。

    错误码 简写说明 错误说明
    REG_BADBR BR=back reference 非法使用返回引用操作符
    REG_BADPAT PAT=pattern 非法使用正则表达式操作符,例如group和list
    REG_BADRPT RPT=repetition 非法使用重复的操作符,例如在第一个字符使用 ’*’
    REG_EBRACE EBRACE=error brace 大括号不匹配
    REG_EBRACK EBRACK=error bracket 中括号不匹配
    REG_ECOLLATE ECOLLATE=error collate 非法参数
    REG_ECTYPE ECTYPE=error character type 错误的字符类型
    REG_EEND EEND=error end 无具体错误。该错误码在POSIX.2中没有定义
    REG_EESCAPE EESCAPE=error escape 多余的\
    REG_EPAREN EPAREN=error parenthesis 圆括号不匹配
    REG_ERANGE ERANGE=error range 非法使用范围操作符,例如结束的标识出现在开始标识之前
    REG_ESIZE ESIZE=error size 编译正则表达式需要的内存大于64kb,在POSIX.2中没有定义
    REG_ESPACE ESPACE=error space 编译正则表达式已经超出内存空间
    REG_ESUBREG ESUBREG=error reference to a subexpression 非法使用子表达式的引用

2.5 regfree

  • 函数原型

    void regfree(regex_t *preg);
  • 功能

    释放由regcomp编译preg的内存

  • 参数含义

    经过regcomp编译的正则表达式

  • 返回值

    void

3 C++的简单封装

可以使用C++进行简单的封装,使其更好用一些

// cregex.h
#include <vector>
#include <string>
#include <regex.h>
using std::string;
using std::vector;

class CStringMatch;             // 预先声明类

class CRegex
{
public:
    CRegex(const string& sPattern,int cflags=REG_EXTENDED);
    virtual ~CRegex();
    string GetErrMsg();
    CStringMatch Match(const string& sStr,int cflags=0);
    bool init(const string& sPattern,int cflags=REG_EXTENDED);
    operator bool() const {return m_isValid;}
private:
    regex_t m_regex;
    int m_cflags;
    bool m_isValid;
    int m_errcode;
    bool isRegMatchUsed(const regmatch_t& sRegMatch);
};

class CStringMatch
{
public:
    CStringMatch(const string& str):m_sStr(str){
    }
    virtual ~CStringMatch(){};
    string GetMatchContent(unsigned int index){
        return string(m_sStr.c_str()+m_vMatchPlaces[index].rm_so,
                      m_sStr.c_str()+m_vMatchPlaces[index].rm_eo);
    }
    regmatch_t GetMatchPlace(unsigned int index){
        return m_vMatchPlaces.at(index);
    }
    operator bool() const {return m_isValid;}
private:
    string m_sStr;
    friend CStringMatch CRegex::Match(const string& sStr,int cflags);
    bool m_isValid;
    vector<regmatch_t> m_vMatchPlaces;
};
// cregex.cpp
#include "cregex.h"
CRegex::CRegex(const string& sPattern,int cflags)
{
    init(sPattern,cflags);
}
bool CRegex::init(const string& sPattern,int cflags)
{
    memset(&m_regex,‘\0‘,sizeof(m_regex));
    m_errcode = regcomp(&m_regex,sPattern.c_str(),cflags);
    if(m_errcode != 0)
    {
        m_isValid = false;
    }
    m_isValid = true;
    return m_isValid;
}
CRegex::~CRegex()
{
    regfree(&m_regex);
}
string CRegex::GetErrMsg()
{
    char szErrMsg[1024+1] = "";
    regerror(m_errcode, &m_regex, szErrMsg, sizeof(szErrMsg));
    return szErrMsg;
}
CStringMatch CRegex::Match(const string& sStr,int cflags)
{
    const unsigned int iMax = 20;
    regmatch_t pResults[iMax];
    memset(pResults,‘\0‘,sizeof(pResults));
    CStringMatch cMatchResult(sStr);
    m_errcode = regexec(&m_regex,sStr.c_str(),iMax,pResults,cflags);
    if(m_errcode == 0)
    {
        cMatchResult.m_isValid = true;
        unsigned int i = 0;
        for (i = 0; i < iMax; ++i) {
            if(isRegMatchUsed(pResults[i]))
            {
                cMatchResult.m_vMatchPlaces.push_back(pResults[i]);
            }
        }
    }
    else
    {
        cMatchResult.m_isValid = false;
    }
    return cMatchResult;
}
bool CRegex::isRegMatchUsed(const regmatch_t& sRegMatch)
{
    return sRegMatch.rm_so != -1;
}

这样使用时,只需要用正则字符串构造一个CRegex对象,并且它的match方法接收一个字符串作为匹配,并返回CStringMatch对象,使用CStringMatch对象的GetMatchContent方法获取捕获的内容

例如:

CRegex cRegex("(.*)省(.+)市/县([^行]+(行股份有限公司|股份有限公司|行|社))(.*)");
if(cRegex)
{    CStringMatch cMatches = cRegex.Match(sBankName);
    if(cMatches)
    {
        sBankNameElements.province = cMatches.GetMatchContent(1);
        sBankNameElements.city = cMatches.GetMatchContent(2);
        sBankNameElements.bank=cMatches.GetMatchContent(3);
        sBankNameElements.keywords=cMatches.GetMatchContent(5);
        DEBUG_LOG("province=[%s],city=[%s],bank=[%s],keywords=[%s]",sBankNameElements.province.c_str(),sBankNameElements.city.c_str(),sBankNameElements.bank.c_str(),sBankNameElements.keywords.c_str());
        return true;
    }
    else
    {
        Trace(L_DEBUG, __FILE__, __LINE__, NULL, cRegex.GetErrMsg().c_str());
    }
}else{
    Trace(L_DEBUG, __FILE__, __LINE__, NULL, cRegex.GetErrMsg().c_str());
}
时间: 2024-10-13 11:50:42

Posix正则表达式API说明的相关文章

Java魔法堂:深入正则表达式API

目录 一.前言 二.正则表达式的使用诉求 三.java.util.regex包 四.java.lang.String实例 五.最短路径实现诉求 六.Java支持的正则表达式功能语法 七.总结 八.参考 一.前言   正则表达式作为文本处理的利器,早已成为各大语言的必要装备,但各语言对其的实现程度(功能语法支持程度)和API设计均有所差异,本篇将目光投向java原生类库中提供的正则表达式API-- java.util.regex包 和 java.lang.String实例方法 ,和所支持的功能语法

POSIX 正则表达式 BRE与ERE的差异

POSIX 正则表达式 传统上,POSIX 定义了两种正则表达式语法, 即:基本正则表达式(BRE)和扩展正则表 达式(ERE).大多数linux程序至少要符合BRE规范. linux中,不同的程序支持的REGXP也不同,如sed只支持BRE的大部分,这主要是收到速度的限制. sed编辑器要尽可能快的处理数据流中的文本.而grep可以支持ERE,不过要使用-E 选项. gawk使用BRE引擎. 其中, BRE 定义的语法符号包括: . - 匹配任意一个字符. [] - 字符集匹配,匹配方括号中定

POSIX正则表达式

POSIX正则表达式 分类: 项目相关2010-09-26 16:16 2131人阅读 评论(0) 收藏 举报 正则表达式graphbasicpython存储unix 正则表达式(regular expression)是一种表示方式,在许多地方均有对此的支持,如命令grep.语言Python.工具vim等.但是这里仅讨论POSIX正则表达式,显然它与其他正则表达式(如传统的Unix正则表达式)存在稍许的差异.POSIX正则表达式分为:BRE(Basic Regular Expression)和E

PHP学习笔记之POSIX正则表达式

1 基础知识 正则表达式是一种描述一段文本模式的方法.到目前为止,我们前面所用到过的精确(文字)匹配也是一种正则表达式.例如,前面我们曾搜索过正则表达式的术语,像"shop"和"delivery". 在PHP中,匹配正则表达式更有点像strstr()匹配,而不像相等比较,因为是在一个字符串的某个位置(如果不指明则可能在字符串中的任何位置)匹配另一个字符串.例如,字符串"shop"匹配正则表达式"shop".它也可以匹配正则表达

LAMPW网站搭建(一)

环境介绍 L:Linux操作系统CentOS 7.2 64位 A:web服务器Apache httpd-2.4.27 M:数据库mysql-5.7.19 P:后台脚本语言php-7.1.7 W:后台管理系统wordpress-4.8 Step 0:准备工作 apache及相关下载: https://www.apache.org/index.html#projects-list 在这个地址里面找到HTTP Server下载httpd,找到APR下载apr和apr-util.在上面也可以看到关于ap

JAVA 正则表达式 (超详细)

(PS:这篇文章为转载,我不喜欢转载的但我觉得这篇文章实在是超赞了,就转了过来,这篇可以说是学习JAVA正则表达的必读篇.作者是个正真有功力的人,阅读愉快) 在Sun的JavaJDK 1.40版本中,Java自带了支持正则表达式的包,本文就抛砖引玉地介绍了如何使用java.util.regex包. 可粗略估计一下,除了偶尔用Linux的外,其他Linu x用户都会遇到正则表达式.正则表达式是个极端强大工具,而且在字符串模式-匹配和字符串模式-替换方面富有弹性.在Unix世界里,正则表达式几乎没有

Java 正则表达式(精华)

英文:Jakob Jenkov译文:严亮链接:ifeve.com/java-regex/ Java 提供了功能强大的正则表达式API,在java.util.regex 包下.本教程介绍如何使用正则表达式API. 正则表达式 一个正则表达式是一个用于文本搜索的文本模式.换句话说,在文本中搜索出现的模式.例如,你可以用正则表达式搜索网页中的邮箱地址或超链接. 正则表达式示例 下面是一个简单的Java正则表达式的例子,用于在文本中搜索 http:// String text = "This is th

刨根究底正则表达式之一——正则表达式简介

声明: 本系列文章的主要参考书有: <精通正则表达式>英文版及中文版 作者: Jeffrey E·F·Friedl 译者:余晟 电子工业出版社 2012-07 <正则指引>作者:余晟 电子工业出版社 2012-05 <正则表达式必知必会>作者:Ben Forta 译者:杨涛 人民邮电出版社2015-01 <冒号课堂:编程范式与OOP思想>作者:郑晖 电子工业出版社 2009-10 同时,还参考了网上的大量资料,除了少部分资料由于未作大量修改(但基本上也有少量

PHP正则表达式简介

PHP支持两种风格的正则表达式语法:POSIX和Perl.POSIX风格的正则表达式更容易掌握,但不能安全用于二进制模式,而Perl兼容的正则表达式相对比较复杂. 正则表达式就是有普通字符(如a~z)和特殊字符(称为元字符)组成的字符串模式.使用正则表达式可以完成以下功能:①测试字符串的某个模式:②替换文本:③根据模式匹配从字符串中提取一个子字符串. 一.POSIX风格的正则表达式 1.编写正则表达式 正则表达式是有普通字符和元字符组成的,通过元字符和普通字符的不同组合,可以写出不同意义的正则表