使用std :: regex查找函数的内容

时间:2016-02-26 07:31:04

标签: c++ regex string parsing substring

所以让我说我有一个带有一些任意代码的主函数:

void main(){
    //Some random code    
    int a = 5;
    int b = a + 7;
}

并且该函数的文本存储在std :: string:

std::string mystring("void main(){ //Some random code  int a = 5; int b = a + 7;}");

我想使用std :: regex来提取函数的主体。所以我要回来的结果是:

"//Some random code int a= 5; int b = a + 7;"

我的问题是我不知道如何格式化正则表达式以获得我想要的东西。这是我现在的代码:

std::string text("void main(){ //Some random code  int a = 5; int b = a + 7;}");
std::regex expr ("void main()\\{(.*?)\\}");

std::smatch matches;

if (std::regex_match(text, matches, expr)) {
    for (int i = 1; i < matches.size(); i++) {
        std::string match (matches[i].first, matches[i].second);
        std::cout << "matches[" << i << "] = " << match << std::endl;
    }
}

我的正则表达式完全关闭并且不返回任何匹配项。我需要做什么才能让我的正则表达式工作?

2 个答案:

答案 0 :(得分:0)

正如评论中所讨论的,OP只想&#34;提取函数体内的文本,无论该文本是什么&#34;

@OP: 你的正则表达式是错误的,因为你没有逃避main()的括号。 将正则表达式更改为"void main\\(\\)\\{(.*?)\\}"将起作用。

我还建议您在for循环中使用size_t i,这样您就不会将签名与无符号(std::smatch::size()返回size_t)进行比较。< / p>

#include <iostream>
#include <regex>

int main()
{
    std::string text("void main(){ //Some random code  int a = 5; int b = a + 7;}");
    std::regex expr("void main\\(\\)\\{(.*?)\\}");

    std::smatch matches;

    if (std::regex_match(text, matches, expr)) {
        for (size_t i = 1; i < matches.size(); i++) {
            std::string match(matches[i].first, matches[i].second);
            std::cout << "matches[" << i << "] = " << match << std::endl;
        }
    }
}

输出:

matches[1] =  //Some random code  int a = 5; int b = a + 7;

对于输入"void main(){ while(true){ //Some random code int a = 5; int b = a + 7; } }"

,此解决方案失败

最简单的解决方案是将正则表达式更改为"^void main\\(\\)\\{(.*?)\\}$",但这需要输入以"void main(){"开头,以"}"结尾

正如 Revolver_Ocelot 所提出的,您还可以在正则表达式中添加一些空格匹配,以使其更灵活。

答案 1 :(得分:0)

正如您的用例中所建议的那样,最好只依靠字符串搜索和大括号匹配。

#include <iostream>
#include <regex>


std::string getBody(const std::string& functionDef, const std::string& text)
{
    size_t pos = 0;
    do
    {
        if ((pos = text.find(functionDef, pos)) == std::string::npos)
            continue;

        pos += functionDef.length();

        size_t firstSemicolon = text.find(";", pos);
        size_t firstOpen = text.find("{", pos);
        size_t firstClose = text.find("}", pos);

        if (firstSemicolon != std::string::npos && firstSemicolon < firstOpen) //Only function declaration
            continue;

        if (firstOpen == std::string::npos || firstClose == std::string::npos || firstClose < firstOpen) //Mismatch
            continue;

        size_t bodyStart = pos = firstOpen + 1;
        size_t bracesCount = 1;
        do
        {
            firstOpen = text.find("{", pos);
            firstClose = text.find("}", pos);

            if (firstOpen == std::string::npos && firstClose == std::string::npos)//Mismatch
            {
                pos = std::string::npos;
                continue;
            }

            //npos is always larger
            if (firstOpen < firstClose)
            {
                bracesCount++;
                pos = firstOpen + 1;
            }
            else if (firstOpen > firstClose)
            {
                bracesCount--;
                if (bracesCount == 0)
                {
                    size_t bodySize = firstClose - bodyStart;
                    return text.substr(bodyStart, bodySize);
                }
                pos = firstClose + 1;
            }
            else
            {
                //Something went terribly wrong...
                pos = std::string::npos;
                continue;
            }

        } while (pos != std::string::npos);
    }
    while (pos != std::string::npos);
    return std::string();
}

int main()
{
    std::string text("void main(); int test(); void main(){ while(true){ //Some {random} code int a = 5; int b = a + 7; } } int test(){ return hello; } ");
    std::cout << getBody("void main()", text) << std::endl;
    std::cout << getBody("int test()", text) << std::endl;
}

输出:

 while(true){ //Some {random} code int a = 5; int b = a + 7; }
 return hello;

代码也可以处理换行符并跳过函数声明。我试着尽可能清楚地写出它。

如果还有问题可以随意提问。