【问题标题】:How to handle regular expression?如何处理正则表达式?
【发布时间】:2019-04-29 03:18:05
【问题描述】:

我有一个需要解析的数据列表。 数据如下:

元素1 \t 可选元素2 \t 可选元素3 \r\n

元素(值)由 '\t' 分隔,OptionalElement2 和/或 OptionalElement3 可能出现也可能不出现。这意味着,我可以:

元素1 \t \t 可选元素3 \r\n

元素1 \t 可选元素2 \r\n

元素1 \r\n

我想在 C 或 C++ 语言中使用 sscanf 用正则表达式读取值,用

while (counter < 3) {
    memset(buffer[counter], '\0', sizeof(buffer[counter])); 
    counter++;
}
sscanf(toParse, "%[^\t]%[^\t\r\n]%[^\t\r\n]\r\n", buffer[0], buffer[1], buffer[2])

但是当 OptionalElement2 为空时,buffer[1] 获取 OptionalElement3 的值而不是 '\0' 的数组。 有没有办法正确处理这个问题,这样当值不存在时,它们相应的容器也是空的?

谢谢。

【问题讨论】:

  • 如果您只是想解析带有制表符分隔内容的字符串,您可能需要查看strtok。您应该决定要使用哪种语言。对于 C++,可能有不同的解决方案。
  • sscanf 不使用正则表达式。如果您完全使用sscanf,则必须始终检查其返回值。
  • 感谢您的回复。然而,我不只是想解析这些值,因为每个值都需要处理。我会尝试 strtok 看看它是如何处理的。
  • melpomene,因为有 2 个案例的返回值完全相同,我认为获取找到的元素数量没有帮助。
  • melpomene,“sscanf 不使用正则表达式”?但我正在将此函数与正则表达式一起使用。

标签: c++ c regex scanf


【解决方案1】:

我的主要问题是,您使用的是 C 还是 C++?结果和适当/预期的答案将与正确的信息一起给出。

当您也在谈论 C++ 时,我将使用 C++ 中提供的库(从 C++11 开始)放置一个示例代码来管理它。 请注意,与我在 C++ 中相比,我没有使用 sscanf(...) 因此,如果您希望将 sscanf 用于您的解决方案,它可能会或可能不会回答您的请求。

这里是示例代码:

#include <regex>
#include <iostream>

int main ()
{
    std::string val{"Element1 \t OptionalElement2 \t OptionalElement3"};
    //std::string val{"Element1 \t OptionalElement2"};
    //std::string val{"Element1"};

    // the match object
    std::smatch m;
    // declare regular expression for matching (note that optional elements are marked as optional with the ? after
    // closing parenthesis
    std::regex myreg("^\\s*([\\w\\d]+)\\s*([\\w\\d]+)?\\s*([\\w\\d]+)?\\s*$");

    // check if there the match between our pattern and the content
    if( std::regex_match(val, m, myreg) )
    {
        // here there will be 4 values available
        // m[0]: the full line
        // m[1]: element 1
        // m[2] : Optional element 2 or an empty string if not found
        // m[3] : Optional element 3 or an empty string if not found
        std::clog << "Size of results:" << m.size() << "\n";

        // display one element
        std::cout << "Element 1: " << m[1] << "\n";
        if( m[2].matched)
            std::cout << "Element 2: " << m[2] << "\n";

        if( m[3].matched)
            std::cout << "Element 3: " << m[3] << "\n";

        // if you want to display all matched elements, here is the code
        /*for (const auto& entry: m)
        {
            if( entry.matched)
                std::clog << "Found: " << entry.str() << "\n";
        }*/
    }

    return 0;
}

同样,鉴于我掌握的信息,它可能无法满足您的要求,但至少您现在有一个可用的 C++ 版本。

【讨论】:

  • 感谢您的回答。我正在使用 C++11 并将使用正则表达式。使用正则表达式而不是 sscanf 是否会降低性能?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-23
  • 2011-09-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多