`

C语言正则表达式

阅读更多
1.int regcomp (regex_t *compiled, const char *pattern, int cflags)

这个函数把指定的规则表达式pattern编译成一种特定的数据格式compiled,这样可以使匹配更有效。函数regexec 会使用这个数据在目标文本串中进行模式匹配。执行成功返回0。

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

pattern 是指向我们写好的规则表达式的指针。
cflags 有如下4个值或者是它们或运算(|)后的值:
REG_EXTENDED 以功能更加强大的扩展规则表达式的方式进行匹配。
REG_ICASE 匹配字母时忽略大小写。
REG_NOSUB 不用存储匹配后的结果。
REG_NEWLINE 识别换行符,这样'$'就可以从行尾开始匹配,'^'就可以从行的开头开始匹配。

2. int regexec (regex_t *compiled, char *string, size_t nmatch, regmatch_t matchptr [], int eflags)

当我们编译好规则表达式后,就可以用regexec 匹配我们的目标文本串了,如果在编译规则表达式的时候没有指定cflags的参数为REG_NEWLINE,则默认情况下是忽略换行符的,也就是把整个文本串当作一个字符串处理。执行成功返回0。

regmatch_t 是一个结构体数据类型,成员rm_so 存放匹配文本串在目标串中的开始位置,rm_eo 存放结束位置。通常我们以数组的形式定义一组这样的结构。因为往往我们的规则表达式中还包含子规则表达式。数组0单元存放主规则表达式位置,后边的单元依次存放子规则表达式位置。

compiled 是已经用regcomp函数编译好的规则表达式。
string 是目标文本串。
nmatch 是regmatch_t结构体数组的长度。
matchptr regmatch_t类型的结构体数组,存放匹配文本串的位置信息。
eflags 有两个值
REG_NOTBOL 按我的理解是如果指定了这个值,那么'^'就不会从我们的目标串开始匹配。总之我到现在还不是很明白这个参数的意义, 原文如下:
If this bit is set, then the beginning-of-line operator doesn't match the beginning of the string (presumably because it's not the beginning of a line).If not set, then the beginning-of-line operator does match the beginning of the string.
REG_NOTEOL 和上边那个作用差不多,不过这个指定结束end of line。

3. void regfree (regex_t *compiled)

当我们使用完编译好的规则表达式后,或者要重新编译其他规则表达式的时候,我们可以用这个函数清空compiled指向的regex_t结构体的内容,请记住,如果是重新编译的话,一定要先清空regex_t结构体。

4. size_t regerror (int errcode, regex_t *compiled, char *buffer, size_t length)

当执行regcomp 或者regexec 产生错误的时候,就可以调用这个函数而返回一个包含错误信息的字符串。

errcode 是由regcomp 和 regexec 函数返回的错误代号。
compiled 是已经用regcomp函数编译好的规则表达式,这个值可以为NULL。
buffer 指向用来存放错误信息的字符串的内存空间。
length 指明buffer的长度,如果这个错误信息的长度大于这个值,则regerror 函数会自动截断超出的字符串,但他仍然会返回完整的字符串的长度。所以我们可以用如下的方法先得到错误字符串的长度。
size_t length = regerror (errcode, compiled, NULL, 0);


----------------------------------------------------------------------
如果用户熟悉Linux下的sed、awk、grep或vi,那么对正则表达式这一概念肯定不会陌生。由于它可以极大地简化处理字符串时的复杂度,因此现在已经在许多Linux实用工具中得到了应用。千万不要以为正则表达式只是Perl、Python、Bash等脚本语言的专利,作为C语言程序员,用户同样可以在自己的程序中运用正则表达式。

标准的C和C++都不支持正则表达式,但有一些函数库可以辅助C/C++程序员完成这一功能,其中最著名的当数Philip Hazel的Perl-Compatible Regular Expression库,许多Linux发行版本都带有这个函数库。

编译正则表达式

为了提高效率,在将一个字符串与正则表达式进行比较之前,首先要用regcomp()函数对它进行编译,将其转化为regex_t结构:


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




参数regex是一个字符串,它代表将要被编译的正则表达式;参数preg指向一个声明为regex_t的数据结构,用来保存编译结果;参数cflags决定了正则表达式该如何被处理的细节。

如果函数regcomp()执行成功,并且编译结果被正确填充到preg中后,函数将返回0,任何其它的返回结果都代表有某种错误产生。

匹配正则表达式 feedom.net

一旦用regcomp()函数成功地编译了正则表达式,接下来就可以调用regexec()函数完成模式匹配:


int regexec(const regex_t *preg,
const char *string, size_t nmatch,
regmatch_t pmatch[], int eflags);
typedef struct {
regoff_t rm_so;
regoff_t rm_eo;
} regmatch_t;



参数preg指向编译后的正则表达式,参数string是将要进行匹配的字符串,而参数nmatch和pmatch则用于把匹配结果返回给调用程序,最后一个参数eflags决定了匹配的细节。

在调用函数regexec()进行模式匹配的过程中,可能在字符串string中会有多处与给定的正则表达式相匹配,参数pmatch就是用来保存这些匹配位置的,而参数nmatch则告诉函数regexec()最多可以把多少个匹配结果填充到pmatch数组中。当regexec()函数成功返回时,从string+pmatch[0].rm_so到string+pmatch[0].rm_eo是第一个匹配的字符串,而从string+pmatch[1].rm_so到string+pmatch[1].rm_eo,则是第二个匹配的字符串,依此类推。

释放正则表达式

无论什么时候,当不再需要已经编译过的正则表达式时,都应该调用函数regfree()将其释放,以免产生内存泄漏。

网管网bitsCN.com
void regfree(regex_t *preg);




函数regfree()不会返回任何结果,它仅接收一个指向regex_t数据类型的指针,这是之前调用regcomp()函数所得到的编译结果。

如果在程序中针对同一个regex_t结构调用了多次regcomp()函数,POSIX标准并没有规定是否每次都必须调用regfree()函数进行释放,但建议每次调用regcomp()函数对正则表达式进行编译后都调用一次regfree()函数,以尽早释放占用的存储空间。

报告错误信息

如果调用函数regcomp()或regexec()得到的是一个非0的返回值,则表明在对正则表达式的处理过程中出现了某种错误,此时可以通过调用函数regerror()得到详细的错误信息。


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




参数errcode是来自函数regcomp()或regexec()的错误代码,而参数preg则是由函数regcomp()得到的编译结果,其目的是把格式化消息所必须的上下文提供给regerror()函数。在执行函数regerror()时,将按照参数errbuf_size指明的最大字节数,在errbuf缓冲区中填入格式化后的错误信息,同时返回错误信息的长度。

应用正则表达式
中国网管联盟www、bitsCN、com



最后给出一个具体的实例,介绍如何在C语言程序中处理正则表达式。



#include <stdio.h>
#include <sys/types.h>
#include <regex.h>

/* 取子串的函数 */
static char* substr(const char*str,
unsigned start, unsigned end)
{
unsigned n = end - start;
static char stbuf[256];
strncpy(stbuf, str + start, n);
stbuf[n] = 0;
return stbuf;
}
/* 主程序 */
int main(int argc, char** argv)
{
char * pattern;
int x, z, lno = 0, cflags = 0;
char ebuf[128], lbuf[256];
regex_t reg;
regmatch_t pm[10];
const size_t nmatch = 10;
/* 编译正则表达式*/
pattern = argv[1];
z = regcomp(?, pattern, cflags);
if (z != 0){
regerror(z, ?, ebuf, sizeof(ebuf));
fprintf(stderr, "%s: pattern '%s' \n",
ebuf, pattern);
return 1;
}
/* 逐行处理输入的数据 */
while(fgets(lbuf, sizeof(lbuf), stdin))
{
++lno;
if ((z = strlen(lbuf)) > 0 && lbuf[z-1]
网管联盟www.bitsCN.com


== '\n')
lbuf[z - 1] = 0;
/* 对每一行应用正则表达式进行匹配 */
z = regexec(?, lbuf, nmatch, pm, 0);
if (z == REG_NOMATCH) continue;
else if (z != 0) {
regerror(z, ?, ebuf, sizeof(ebuf));
fprintf(stderr, "%s: regcom('%s')\n",
ebuf, lbuf);
return 2;
}
/* 输出处理结果 */
for (x = 0; x < nmatch && pm[x].rm_so != -1; ++ x)
{
if (!x) printf("%04d: %s\n", lno, lbuf);
printf(" $%d='%s'\n", x, substr(lbuf, pm[x].rm_so,
pm[x].rm_eo));
}
}
/* 释放正则表达式 */
regfree(?);
return 0;
}


 上述程序负责从命令行获取正则表达式,然后将其运用于从标准输入得到的每行数据,并打印出匹配结果。执行下面的命令可以编译并执行该程序:


# gcc regexp.c -o regexp
# ./regexp 'regex[a-z]*' < regexp.c
0003: #include <regex.h>
$0='regex'
0027: regex_t reg;
$0='regex'
0054: z = regexec(?, lbuf, nmatch, pm, 0);
$0='regexec'


54com.cn



小结

对那些需要进行复杂数据处理的程序来说,正则表达式无疑是一个非常有用的工具。本文重点在于阐述如何在C语言中利用正则表达式来简化字符串处理,以便在数据处理方面能够获得与Perl语言类
似的灵活性。
【转自www.bitsCN.com】
分享到:
评论

相关推荐

    C语言正则表达式库

    C语言正则表达式库是用于在C编程环境中处理和匹配正则表达式的软件库。这个库名为PCRE(Perl Compatible Regular Expressions),正如其名,它与Perl语言中的正则表达式语法高度兼容,提供了丰富的功能和强大的匹配...

    C语言正则表达式使用详解

    ### C语言正则表达式使用详解 #### 一、引言 正则表达式作为一种强大的文本处理工具,在数据检索和高级编程中应用广泛。对于C语言开发者而言,虽然标准的C语言本身并不直接支持正则表达式的操作,但是可以通过相关...

    C语言正则表达式详解 regcomp() regexec() regfree()详解1

    在C语言中,由于标准库并不直接支持正则表达式,程序员需要借助第三方库来实现这一功能。Perl-Compatible Regular Expression(PCRE)库是一个广泛使用的选项,它为C和C++程序员提供了处理正则表达式的能力。在C语言...

    Linux下的C语言正则表达式

    ### Linux下的C语言正则表达式使用详解 #### 引言 正则表达式作为一种强大的文本处理工具,广泛应用于各种编程语言中。对于C语言来说,尽管标准库并不直接支持正则表达式的操作,但可以通过引入第三方库来实现这一...

    正则表达式(regex)C语言源码,超强查找/替换算法

    在C语言中,实现正则表达式功能通常需要借助第三方库,比如本案例中提到的Henry Spencer的regex library。这个库提供了在C语言环境中使用正则表达式的功能,具有高度可移植性和简洁的API。 **1. Henry Spencer的...

    C语言实现正则表达式检测

    这里我们将深入探讨如何在C语言中实现正则表达式的检测,基于提供的"ValidateLib.c"和"Validate.h"文件,我们可以推断这是一个自定义的正则表达式验证库。 首先,让我们理解正则表达式的概念。正则表达式(Regular ...

    C语言正则表达式[参照].pdf

    C语言正则表达式主要涉及三个关键步骤:编译、匹配和释放。 1. **编译正则表达式**: 使用`regcomp()`函数来编译正则表达式字符串。这个函数接受三个参数:一个`regex_t`结构体指针用于存储编译后的结果,一个包含...

    C语言写的正则表达式

    linux下 用C语言 写的正则表达式

    c语言正则表达式pcre

    C语言正则表达式PCRE(Perl Compatible Regular Expressions)是一种强大的文本模式匹配库,它在C编程中广泛用于处理字符串和数据的模式查找。PCRE库提供了与Perl语言正则表达式语法相兼容的功能,使得C程序员可以...

    在C语言中使用正则表达式

    在C语言中使用正则表达式可以为程序增添强大的文本处理能力。正则表达式是一种模式匹配工具,常用于搜索、替换和提取文本中的特定模式。C语言标准库提供了`&lt;regex.h&gt;`头文件,支持基本的正则表达式操作。然而,与...

    正则表达式 到 nfa dfa

    正则表达式是一种强大的文本处理工具,用于匹配和操作字符串。它们在编程语言、文本编辑器和搜索引擎等众多领域有着广泛的应用。NFA(非确定性有限状态自动机)和DFA(确定性有限状态自动机)是计算理论中用于识别...

    C正则表达式库

    在C语言环境中,GUN(GNU)提供了一个官方的正则表达式库,这使得C程序员可以方便地在他们的应用程序中利用正则表达式的强大功能。本篇文章将详细探讨GUN C的正则表达式库,包括其核心组件`regex.c`和`regex.h`,...

    正则表达式转换为nfa以c语言源程序

    代码相对简单; c语言实现; 正则表达式转换为nfa;

    C语言环境正则表达式支持库

    "C语言环境正则表达式支持库"是指在C编程语言中,用于实现正则表达式功能的库。这些库通常提供一系列函数,允许程序员在自己的程序中集成正则表达式的功能,进行复杂的数据处理和文本分析。 正则表达式的基本词元是...

    正则表达式在C语言中的应用

    在C语言中,虽然标准库没有内置正则表达式的支持,但可以通过第三方库如POSIX(Portable Operating System Interface)来实现正则表达式功能。POSIX标准定义了一套API,使得在C语言中使用正则表达式变得可能。 首先...

    C/C++ Regex/Regular Expression(C/C++正则表达式库实现)

    在C语言中,我们通常需要依赖第三方库来实现正则表达式。 C++11及后续版本中的`&lt;regex&gt;`库提供了丰富的API,包括构造正则表达式对象、执行匹配、提取匹配分组等。以下是一些关键的概念和函数: 1. **正则表达式...

    电话号码及日期时间提取(正则表达式 C)

    在本项目中,“电话号码及日期时间提取(正则表达式 C)”是一个使用C语言编写的程序,它能够从文本中有效地识别和提取中国大陆的手机号码和固定电话号码,以及简体中文网页中的日期和时间信息。 首先,我们要理解...

    C语言正则表达式REEC.zip

    REEC是一个精简,高效的C语言正则表达式引擎,它使得C语言开发中支持正则表达式,目前已经进化到了1.2.0版本,可以说无论从功能上,还是效率都到达了很好的应用水平,该引擎除支持常用的正则标准之外,还有一些原创...

    正则表达式C语言源码

    C语言,作为一门基础且通用的编程语言,虽然没有内置的正则表达式库,但可以通过第三方库来实现正则表达式功能。在这个“正则表达式C语言源码”中,我们主要关注的是PCRE(Perl Compatible Regular Expressions)库...

Global site tag (gtag.js) - Google Analytics