当前时区为 UTC + 8 小时



发表新帖 回复这个主题  [ 11 篇帖子 ] 
作者 内容
1 楼 
 文章标题 : 我实在用不好 regex(C正则表达式库)了, 求达人帮忙!
帖子发表于 : 2010-03-03 22:20 
头像

注册: 2009-05-20 21:43
帖子: 735
送出感谢: 2
接收感谢: 2
我的示例代码如下, 提取并输出一个字符串中以逗号或分号分隔的单词列表:
代码:
#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'
到底问题出在那里, 恳请达人帮助! 谢谢!!!


_________________
http://wonc.me/


最后由 潇洒走一回 编辑于 2010-03-04 19:58,总共编辑了 3 次

页首
 用户资料  
 
2 楼 
 文章标题 : Re: 我实在用不好 regex(C正则表达式库)了, 求达人帮忙!
帖子发表于 : 2010-03-04 20:00 
头像

注册: 2009-05-20 21:43
帖子: 735
送出感谢: 2
接收感谢: 2
:em19 555~ 都不甩我...


_________________
http://wonc.me/


页首
 用户资料  
 
3 楼 
 文章标题 : Re: 我实在用不好 regex(C正则表达式库)了, 求达人帮忙!
帖子发表于 : 2010-03-04 22:43 
头像

注册: 2007-06-15 21:19
帖子: 196
地址: 上海
送出感谢: 0 次
接收感谢: 0 次
regexec只会匹配一次,需要自己手动写循环来匹配多个。

pmatch是用来存储一次匹配产生的多组数据的,只要把你的pattern改成 "\\<(.)([^,;]+)\\>" ,就能看出来了。


_________________
/****************************************************
/* Work hard, play harder.
/****************************************************


页首
 用户资料  
 
4 楼 
 文章标题 : Re: 我实在用不好 regex(C正则表达式库)了, 求达人帮忙!
帖子发表于 : 2010-03-04 23:41 
头像

注册: 2009-05-20 21:43
帖子: 735
送出感谢: 2
接收感谢: 2
den 写道:
regexec只会匹配一次,需要自己手动写循环来匹配多个。

pmatch是用来存储一次匹配产生的多组数据的,只要把你的pattern改成 "\\<(.)([^,;]+)\\>" ,就能看出来了。

我知道你说的意思了... 首先万分感谢!
可是那样也太麻烦了吧? 循环匹配倒不算什么... 经我测试, 要想在一个字符串匹配多个结果, 每次匹配到一个结果后 需要把已经匹配的子串摘掉 才能在剩下的字符串继续寻找匹配(不要妄想regexec会记住上次匹配的位置)... 比如说: 在 "lily, lucy, kate" 中匹配出lily后, 再次调用regexec它还会从开头匹配, 所以必须把第一个匹配结果移除...


_________________
http://wonc.me/


页首
 用户资料  
 
5 楼 
 文章标题 : Re: 我实在用不好 regex(C正则表达式库)了, 求达人帮忙!
帖子发表于 : 2010-03-05 0:28 
头像

注册: 2009-05-20 21:43
帖子: 735
送出感谢: 2
接收感谢: 2
感谢 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!!!


_________________
http://wonc.me/


页首
 用户资料  
 
6 楼 
 文章标题 : Re: 我实在用不好 regex(C正则表达式库)了, 求达人帮忙!
帖子发表于 : 2010-07-13 17:22 

注册: 2010-07-13 17:04
帖子: 96
送出感谢: 15
接收感谢: 0 次
我想用下边这段进行惰性匹配,但匹配出了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
帖子: 735
送出感谢: 2
接收感谢: 2
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了.


_________________
http://wonc.me/


最后由 潇洒走一回 编辑于 2010-09-06 10:56,总共编辑了 2 次

页首
 用户资料  
 
8 楼 
 文章标题 : Re: 我实在用不好 regex(C正则表达式库)了, 求达人帮忙!
帖子发表于 : 2010-09-06 10:52 
头像

注册: 2005-08-14 21:55
帖子: 58428
地址: 长沙
送出感谢: 4
接收感谢: 274
.*?是最短匹配。表示匹配 xxxxis 而不是 xxxisandis
还有可预见匹配。哎。这都是perl玩的。C里面不痛苦啊,那些匹配前,匹配后,匹配结果等。。。都估计用不上了吧。
引用:
$` 在上个格式匹配信息前的字符串
$& 与上个格式匹配的字符串
$’ 在上个格式匹配信息后的字符串


_________________
● 鸣学


页首
 用户资料  
 
9 楼 
 文章标题 : Re: 我实在用不好 regex(C正则表达式库)了, 求达人帮忙!
帖子发表于 : 2010-09-06 10:54 
头像

注册: 2009-05-20 21:43
帖子: 735
送出感谢: 2
接收感谢: 2
eexpress 写道:
.*?是最短匹配。表示匹配 xxxxis 而不是 xxxisandis
还有可预见匹配。哎。这都是perl玩的。C里面不痛苦啊,那些匹配前,匹配后,匹配结果等。。。都估计用不上了吧。
引用:
$` 在上个格式匹配信息前的字符串
$& 与上个格式匹配的字符串
$’ 在上个格式匹配信息后的字符串

据说Perl正则很强大的, 可惜我没学. 你后面里面说的三个规则, Boost.Regex里面支持的很好.
Boost.Regex同时支持POSIX和Perl的规则 .


_________________
http://wonc.me/


页首
 用户资料  
 
10 楼 
 文章标题 : Re: 我实在用不好 regex(C正则表达式库)了, 求达人帮忙!
帖子发表于 : 2010-09-15 22:10 

注册: 2008-10-31 22:12
帖子: 6546
系统: 践兔
送出感谢: 18
接收感谢: 25
用perl


_________________
代码:
] ls -ld //


页首
 用户资料  
 
11 楼 
 文章标题 : Re: 我实在用不好 regex(C正则表达式库)了, 求达人帮忙!
帖子发表于 : 2011-10-11 15:13 

注册: 2011-05-09 10:30
帖子: 2
送出感谢: 0 次
接收感谢: 0 次
解决了我问题 谢谢


页首
 用户资料  
 
显示帖子 :  排序  
发表新帖 回复这个主题  [ 11 篇帖子 ] 

当前时区为 UTC + 8 小时


在线用户

正在浏览此版面的用户:没有注册用户 和 2 位游客


不能 在这个版面发表主题
不能 在这个版面回复主题
不能 在这个版面编辑帖子
不能 在这个版面删除帖子
不能 在这个版面提交附件

前往 :  
本站点为公益性站点,用于推广开源自由软件,由 DiaHosting VPSBudgetVM VPS 提供服务。
我们认为:软件应可免费取得,软件工具在各种语言环境下皆可使用,且不会有任何功能上的差异;
人们应有定制和修改软件的自由,且方式不受限制,只要他们自认为合适。

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
简体中文语系由 王笑宇 翻译