打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
Ubuntu中文论坛 ? 查看主题 - 我实在用不好 regex(C正则表达式库)了, 求达人帮忙!
我实在用不好 regex(C正则表达式库)了, 求达人帮忙!
发表于 : 2010-03-03 22:20
注册: 2009-05-20 21:43
帖子: 625 我的示例代码如下, 提取并输出一个字符串中以逗号或分号分隔的单词列表:
代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <regex.h>
int main(int argc, char** argv)
{
int i = 0;
int res;
int len;
char result[BUFSIZ];
char err_buf[BUFSIZ];
char* src = argv[1];   /* 源由命令行参数指定 */
const char* pattern = "\\<[^,;]+\\>";
regex_t preg;
regmatch_t pmatch[10];
if( (res = regcomp(&preg, pattern, REG_EXTENDED)) != 0)
{
regerror(res, &preg, err_buf, BUFSIZ);
printf("regcomp: %s\n", err_buf);
exit(res);
}
res = regexec(&preg, src, 10, pmatch, REG_NOTBOL);
//~ res = regexec(&preg, src, 10, pmatch, 0);
//~ res = regexec(&preg, src, 10, pmatch, REG_NOTEOL);
if(res == REG_NOMATCH)
{
printf("NO match\n");
exit(0);
}
for (i = 0; pmatch[i].rm_so != -1; i++)
{
len = pmatch[i].rm_eo - pmatch[i].rm_so;
memcpy(result, src + pmatch[i].rm_so, len);
result[len] = 0;
printf("num %d: '%s'\n", i, result);
}
regfree(&preg);
return 0;
}
可是结果并非我意料, 仅能输出第一个匹配的单词...
如: gcc -o regex regex.c;
./regex 'hello, world'
输出为 num 0: 'hello'
而我预期的结果应为:
num 0: 'hello'
num 1: 'world'
到底问题出在那里, 恳请达人帮助! 谢谢!!!
最后由潇洒走一回 编辑于 2010-03-04 19:58,总共编辑了 3 次
页首
3 楼 den  文章标题 : Re: 我实在用不好 regex(C正则表达式库)了, 求达人帮忙!
发表于 : 2010-03-04 22:43
注册: 2007-06-15 21:19
帖子: 194
地址: 上海 regexec只会匹配一次,需要自己手动写循环来匹配多个。
pmatch是用来存储一次匹配产生的多组数据的,只要把你的pattern改成 "\\<(.)([^,;]+)\\>" ,就能看出来了。
_________________
/****************************************************
/* Work hard, play harder.
/****************************************************
页首  
4 楼 潇洒走一回  文章标题 : Re: 我实在用不好 regex(C正则表达式库)了, 求达人帮忙!
发表于 : 2010-03-04 23:41
注册: 2009-05-20 21:43
帖子: 625 den 写道:
regexec只会匹配一次,需要自己手动写循环来匹配多个。
pmatch是用来存储一次匹配产生的多组数据的,只要把你的pattern改成 "\\<(.)([^,;]+)\\>" ,就能看出来了。
我知道你说的意思了... 首先万分感谢!
可 是那样也太麻烦了吧? 循环匹配倒不算什么... 经我测试, 要想在一个字符串匹配多个结果, 每次匹配到一个结果后 需要把已经匹配的子串摘掉 才能在剩下的字符串继续寻找匹配(不要妄想regexec会记住上次匹配的位置)... 比如说: 在 "lily, lucy, kate" 中匹配出lily后, 再次调用regexec它还会从开头匹配, 所以必须把第一个匹配结果移除...
页首  
5 楼 潇洒走一回  文章标题 : Re: 我实在用不好 regex(C正则表达式库)了, 求达人帮忙!
发表于 : 2010-03-05 0:28
注册: 2009-05-20 21:43
帖子: 625 感谢 den !!! 在他的指点下我破除了网上那些文章的误导, 基本搞懂了 regex 的用法! 下面贴出我重写的小示例, 目的在于演示 linux C 中如何使用 regex 正则表达式 。。。我之所以写的这么啰嗦, 是希望有人通过google搜索时, 他所使用的关键字能被google 定位到这里来。。。
代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <regex.h>
int main(int argc, char** argv)
{
int i = 0;
int res;
int sub_len;
int cut_here;   /* 是一个位置标记 */
char result[BUFSIZ];
char err_buf[BUFSIZ];
char* src = argv[1];   /* 源由命令行参数指定 */
const char* pattern = "[+-](\\<[^,;]+\\>)";
regex_t preg;
regmatch_t pmatch[10];
if( (res = regcomp(&preg, pattern, REG_EXTENDED)) != 0)
{
regerror(res, &preg, err_buf, BUFSIZ);
printf("regcomp: %s\n", err_buf);
exit(res);
}
while(1)
{
res = regexec(&preg, src, 10, pmatch, 0);
if(res == REG_NOMATCH)
{
break;
}
for (i = 0; pmatch[i].rm_so != -1; i++)
{
sub_len = pmatch[i].rm_eo - pmatch[i].rm_so;
memcpy(result, src + pmatch[i].rm_so, sub_len);
result[sub_len] = 0;
if(i == 0)
{
cut_here = pmatch[0].rm_eo;
/* 下次匹配前src将从此处被截断 */
printf("'%s' 成功被匹配, ", result);
}
else
printf("其实我想要的是其中的 '%s' .", result);
}
putchar('\n');
src += cut_here;
/* 在src 中 "砍掉" 已经匹配的子串 */
}
regfree(&preg);
return 0;
}
编译: gcc -o regex regex.c
执行: ./regex '+happy, -sorrow'
输出: 引用:
'+happy' 成功被匹配, 其实我想要的是其中的 'happy' .
'-sorrow' 成功被匹配, 其实我想要的是其中的 'sorrow' .
再次感谢 den!!!
页首  
6 楼 alober  文章标题 : Re: 我实在用不好 regex(C正则表达式库)了, 求达人帮忙!
发表于 : 2010-07-13 17:22
注册: 2010-07-13 17:04
帖子: 1 我想用下边这段进行惰性匹配,但匹配出了This is,我只想匹配出This,应该怎么写呢?望各位老大指点。
代码:
const char *pattern = "(.*?is).*";
char *text = "This is a book.";
//略去其它声明
regcomp(&reg, pattern, REG_EXTENDED);
status = regexec(&reg, text, nm, pm, REG_NOTBOL);
if (status == REG_NOMATCH) {
printf("No match.\n");
} else if (status == 0) {
strncpy(dest, text + pm[1].rm_so,
pm[1].rm_eo - pm[1].rm_so);
printf("%s\n", dest);
}
regfree(&reg);
页首  
7 楼 潇洒走一回  文章标题 : Re: 我实在用不好 regex(C正则表达式库)了, 求达人帮忙!
发表于 : 2010-09-06 10:45
注册: 2009-05-20 21:43
帖子: 625 alober 写道:
我想用下边这段进行惰性匹配,但匹配出了This is,我只想匹配出This,应该怎么写呢?望各位老大指点。
代码:
const char *pattern = "(.*?is).*";
char *text = "This is a book.";
//略去其它声明
regcomp(&reg, pattern, REG_EXTENDED);
status = regexec(&reg, text, nm, pm, REG_NOTBOL);
if (status == REG_NOMATCH) {
printf("No match.\n");
} else if (status == 0) {
strncpy(dest, text + pm[1].rm_so,
pm[1].rm_eo - pm[1].rm_so);
printf("%s\n", dest);
}
regfree(&reg);
我好长时间没研究正则表达试了...
你的 "(.*?is).*" 我看不大明白 ".*" 后面怎么又是一个问号?
非贪婪匹配我没有研究也没有需要过, 我对正则表达式的需求并不复杂.
另外, 我转而使用Boost.Regex了.
最后由潇洒走一回 编辑于 2010-09-06 10:56,总共编辑了 2 次
页首  
8 楼 eexpress  文章标题 : Re: 我实在用不好 regex(C正则表达式库)了, 求达人帮忙!
发表于 : 2010-09-06 10:52
注册: 2005-08-14 21:55
帖子: 43993
地址: 长沙 .*?是最短匹配。表示匹配 xxxxis 而不是 xxxisandis
还有可预见匹配。哎。这都是perl玩的。C里面不痛苦啊,那些匹配前,匹配后,匹配结果等。。。都估计用不上了吧。
引用:
$` 在上个格式匹配信息前的字符串
$& 与上个格式匹配的字符串
$’ 在上个格式匹配信息后的字符串
_________________
居然不认utf8了。
页首  
9 楼 潇洒走一回  文章标题 : Re: 我实在用不好 regex(C正则表达式库)了, 求达人帮忙!
发表于 : 2010-09-06 10:54
注册: 2009-05-20 21:43
帖子: 625 eexpress 写道:
.*?是最短匹配。表示匹配 xxxxis 而不是 xxxisandis
还有可预见匹配。哎。这都是perl玩的。C里面不痛苦啊,那些匹配前,匹配后,匹配结果等。。。都估计用不上了吧。
引用:
$` 在上个格式匹配信息前的字符串
$& 与上个格式匹配的字符串
$’ 在上个格式匹配信息后的字符串
据说Perl正则很强大的, 可惜我没学. 你后面里面说的三个规则, Boost.Regex里面支持的很好.
Boost.Regex同时支持POSIX和Perl的规则 .
页首  
10 楼 tusooa  文章标题 : Re: 我实在用不好 regex(C正则表达式库)了, 求达人帮忙!
发表于 : 2010-09-15 22:10
注册: 2008-10-31 22:12
帖子: 2171 用perl
_________________
决定了:以后再也不用闻到死了。
Bash-Libraries
推荐一下这个。
围观看帖不回的人。
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
C语言正则表达式
专家教您如何在C语言中巧用正则表达式
C语言使用正则表达式
POSIX正则表达式
C语言中嵌入正则表达式
C++中三种正则表达式比较(C regex,C ++regex,boost regex)
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服