免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 6524 | 回复: 8
打印 上一主题 下一主题

linux c正则表达式 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-06-07 10:43 |只看该作者 |倒序浏览
使用POSIX函数库中的Regex系列函数来说明在Linux c下如何使用正则表达式


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

#define ERRBUF 128

static char * substr(const char * str, unsigned start, unsigned end);

int main(int argc, char *argv[])
{
        regex_t myreg;
        char err[ERRBUF];
        int resulta,resultb;
        regmatch_t match[4];
        size_t nmatch = 4;

        char pattern[] = "[0-9]{3}";

        resulta = regcomp(&myreg, pattern, REG_EXTENDED | REG_NEWLINE);

        if(resulta != 0)
        {
                fprintf(stderr, "pattern compiled error\n");
                regerror(resulta, &myreg, err, sizeof(err));
                regfree(&myreg);
                exit(1);
        }

        char mystring[] = "192.168.121.112";

        resultb = regexec(&myreg, mystring, nmatch, match, 0);
        if(resultb != 0)
        {
                regerror(resultb, &myreg, err, sizeof(err));
                regfree(&myreg);
                exit(1);
        }

        int x;
        for(x = 0; x < nmatch && match[x].rm_so != -1; x++)
{
                printf("%s\n",substr(mystring, match[x].rm_so, match[x].rm_eo));
}

        printf("x = %d\n",x);
        regfree(&myreg);
        return 0;
}

static char * substr(const char * str, unsigned start, unsigned end)
{
        unsigned n = end - start;
        static char strbuf[256];
        memset(strbuf,'\0',sizeof(strbuf));
        strncpy(strbuf, str + start ,n);
        strbuf[n] = '\0';
        return strbuf;
}

只能打印出"192",为什么匹配不了后面的内容呢

论坛徽章:
0
2 [报告]
发表于 2010-06-07 10:48 |只看该作者
本帖最后由 liexusong 于 2010-06-07 10:49 编辑

你的正则模式都只是匹配3个数字而已啊!
char pattern[] = "[0-9]{3}";
改为:
char pattern[] = "[0-9.]+";

论坛徽章:
0
3 [报告]
发表于 2010-06-07 10:59 |只看该作者
我没有说清楚
我的意思是想匹配  3个相连数字的字符串
char mystring[] = "192.168.121.112"
应该能匹配到四个地方,分别应该为192  168  121  112
但是却只能打印出192,也就是说只匹配到了一个字段

论坛徽章:
8
CU大牛徽章
日期:2013-04-17 10:59:39CU大牛徽章
日期:2013-04-17 11:01:45CU大牛徽章
日期:2013-04-17 11:02:15CU大牛徽章
日期:2013-04-17 11:02:36CU大牛徽章
日期:2013-04-17 11:02:58技术图书徽章
日期:2013-12-04 10:48:50酉鸡
日期:2014-01-03 10:32:30辰龙
日期:2014-03-06 15:04:07
4 [报告]
发表于 2010-06-07 11:05 |只看该作者
对正则表达式也不熟……


这几天在玩boost的regex。发现想把4段都提取出来,只能这样写: (\d+).(\d+).(\d+).(\d+)

(\d+.?){4}这种写法可以匹配到全部4段,但match中只会保留最后一次匹配(即112)。

想抓类似格式重复但字段数不定的记录,偷懒搞个类似repeat("(\\d+)?.?", MAX_COL_NUM)的东西,却又被提示超过预设复杂度限制。看来还是得啃boost恶心的官方文档。

论坛徽章:
0
5 [报告]
发表于 2010-06-07 11:25 |只看该作者
本帖最后由 tanggula2007 于 2010-06-07 11:30 编辑

regmatch_t match[4];
size_t nmatch = 4;

typedef struct {
       regoff_t rm_so;
       regoff_t rm_eo;
} regmatch_t;
nmatch可以预先指定最多可以匹配的字段数
而rm_so,rm_eo记录的是匹配字段距离字符串开头的偏移量
既然可以匹配多个字段 为什么却匹配不了后面的内容呢

很纳闷

感觉这个posix 正则表达式库函数 比起简单的 linux 命令行,sed,awk,grep等所使用的basic regular express 仅仅是多了一个编译的正则表达式的过程,怎么这么难用

论坛徽章:
0
6 [报告]
发表于 2010-06-07 13:42 |只看该作者
学习一下了啊

论坛徽章:
15
射手座
日期:2014-11-29 19:22:4915-16赛季CBA联赛之青岛
日期:2017-11-17 13:20:09黑曼巴
日期:2017-07-13 19:13:4715-16赛季CBA联赛之四川
日期:2017-02-07 21:08:572015年亚冠纪念徽章
日期:2015-11-06 12:31:58每日论坛发贴之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-07-12 22:20:002015亚冠之浦和红钻
日期:2015-07-08 10:10:132015亚冠之大阪钢巴
日期:2015-06-29 11:21:122015亚冠之广州恒大
日期:2015-05-22 21:55:412015年亚洲杯之伊朗
日期:2015-04-10 16:28:25
7 [报告]
发表于 2010-06-07 14:53 |只看该作者
本帖最后由 yulihua49 于 2010-06-07 15:02 编辑
我没有说清楚
我的意思是想匹配  3个相连数字的字符串
char mystring[] = "192.168.121.112"
应该能匹配 ...
tanggula2007 发表于 2010-06-07 10:59



    你要匹配多次,每次从上次匹配的.rm_eo重新开始。

char *p=mystring;

for(i=1;i<4;i++) if(0==regexec(&myreg,p,nmatch,match,0)) {
................
p=mystring+match[0].rm_eo;
if(*p=='.') p++;
}

论坛徽章:
0
8 [报告]
发表于 2010-06-07 15:08 |只看该作者
回复 7# yulihua49

谢谢ls,原来regexec每次只能匹配一次
    请问LS
若 定义 match[4] 数组
是否就是确定所谓的子表达式
这应该怎么用呢

论坛徽章:
15
射手座
日期:2014-11-29 19:22:4915-16赛季CBA联赛之青岛
日期:2017-11-17 13:20:09黑曼巴
日期:2017-07-13 19:13:4715-16赛季CBA联赛之四川
日期:2017-02-07 21:08:572015年亚冠纪念徽章
日期:2015-11-06 12:31:58每日论坛发贴之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-07-12 22:20:002015亚冠之浦和红钻
日期:2015-07-08 10:10:132015亚冠之大阪钢巴
日期:2015-06-29 11:21:122015亚冠之广州恒大
日期:2015-05-22 21:55:412015年亚洲杯之伊朗
日期:2015-04-10 16:28:25
9 [报告]
发表于 2010-06-15 20:56 |只看该作者
本帖最后由 yulihua49 于 2010-06-15 21:04 编辑
回复  yulihua49

谢谢ls,原来regexec每次只能匹配一次
    请问LS
若 定义 match[4] 数组
是否就是 ...
tanggula2007 发表于 2010-06-07 15:08



    按小括号的前括号编号。
match[0]是整个,match[1]是第一个,其余类推。
"(([0-9]{1,3})\\.){3})[0-9]{1,3}" 试试。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP