所以让我说我有一个带有一些任意代码的主函数:
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;
}
}
我的正则表达式完全关闭并且不返回任何匹配项。我需要做什么才能让我的正则表达式工作?
答案 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;
代码也可以处理换行符并跳过函数声明。我试着尽可能清楚地写出它。
如果还有问题可以随意提问。