【问题标题】:Working with GNU regex functions in C or C++在 C 或 C++ 中使用 GNU 正则表达式函数
【发布时间】:2010-03-01 23:12:32
【问题描述】:

谁能给我完整的示例程序,如何在 gcc C 或 C++ (http://docs.freebsd.org/info/regex/regex.info.GNU_Regex_Functions.html) 中使用 GNU 正则表达式函数, re_pattern_buffer, re_compile_fastmap?

例如,翻译这个 Python 小程序:

import re
unlucky = re.compile('1\d*?3')

nums = ("13", "31", "777", "10003")

for n in nums:
    if unlucky.search(n) is None:
        print "lucky"
    else:
        print "unlucky"

谢谢!

【问题讨论】:

  • 您应该尝试自己翻译。如果您在使用它时遇到问题,请随时发布具体问题。

标签: c++ c regex gcc gnu


【解决方案1】:

好的,在深入研究代码之前,我应该提到您可能想要使用更高级别的库。您确实说过 C++,因此您可以使用 Boost.Regex 等。即使你想留在C,也有更好的选择。我发现POSIX functions 更干净一些,更不用说更便携了。

// Tell GNU to define the non-standard APIs
#define _GNU_SOURCE 
// This is actually the same header used for the POSIX API.
// Except then you obviously don't need _GNU_SOURCE
#include <regex.h> 
#include <stdio.h>
#include <string.h>

int main()
{
    struct re_pattern_buffer pat_buff; // Put a re_pattern_buffer on the stack
    // The next 4 fields must be set.  

    // If non-zero, applies a translation function to characters before 
    // attempting match (http://www.delorie.com/gnu/docs/regex/regex_51.html)
    pat_buff.translate = 0; 
    // If non-zero, optimization technique.  Don't know details.
    // See http://www.delorie.com/gnu/docs/regex/regex_45.html
    pat_buff.fastmap = 0;
    // Next two must be set to 0 to request library allocate memory
    pat_buff.buffer = 0;
    pat_buff.allocated = 0;
    char pat_str[] = "1[^3]*3";
    // This is a global (!) used to set the regex type (note POSIX APIs don't use global for this)
    re_syntax_options = RE_SYNTAX_EGREP; 
    // Compile the pattern into our buffer
    re_compile_pattern(pat_str, sizeof(pat_str) - 1, &pat_buff); 
    char* nums[] = {"13", "31", "777", "10003"}; // Array of char-strings
    for(int i = 0; i < sizeof(nums) / sizeof(char*); i++)
    {
        int match_ret;
        // Returns number of characters matches (may be 0, but if so there's still a match)
        if((match_ret = re_match(&pat_buff, nums[i], strlen(nums[i]), 0, NULL)) >= 0) 
        {
            printf("unlucky\n");
        }
        else if(match_ret == -1) // No match
        {
            printf("lucky\n");
        }
        // Anything else (though docs say -2) is internal library error
        else 
    {
            perror("re_match");
        }
    }
    regfree(&pat_buff);
}

编辑:我添加了对必填字段和 regfree 的更多解释。我之前有幸运/不幸倒退,这解释了部分差异。另一部分是我认为这里可用的任何正则表达式语法都不支持惰性运算符(*?)。在这种情况下,有一个简单的修复方法,使用"1[^3]*3"

【讨论】:

  • 谢谢!但是输出应该是“不幸的幸运幸运不幸”,而我得到了“幸运不幸不幸不幸”。您也可以评论pat_buff.translate = 0; pat_buff.fastmap = 0; pat_buff.buffer = 0; pat_buff.allocated = 0; 部分吗?还有regfree()呢?我们什么时候需要使用它?
  • 至于 Boost.Regex 我不能使用它,因为该程序将在 Boost 不可用的特定环境中工作。可移植性也不是问题——程序只能在特定版本的 gcc 上编译。
  • 谢谢!现在可以了。另外我认为我们可以使用re_set_syntax()函数来代替re_syntax_options global。
  • re_set_syntax 只是设置全局并返回旧值。 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-28
相关资源
最近更新 更多