使用 std::regex 查找函数的内容
use std::regex to find contents of a function
假设我有一个带有任意代码的主函数:
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;
}
}
我的正则表达式完全关闭,不返回任何匹配项。我需要什么来制作我的正则表达式才能使其工作?
正如注释中所讨论的,OP 只想"提取函数体内的文本,而不管该文本是什么"。
@OP:您的正则表达式是错误的,因为您没有转义main()
的括号。将正则表达式更改为"void main\(\)\{(.*?)\}"
将起作用。
我还建议在 for 循环中使用 size_t
for i
,这样您就不会将有符号与无符号进行比较(std::smatch::size()
返回size_t
)。
#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所建议的那样,您还可以在正则表达式中添加一些空格匹配,以使其更加灵活。
正如您的用例中所建议的那样,最好只依靠字符串搜索和大括号匹配。
#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;
该代码还可以处理换行符和跳过函数声明。我试图把它写得尽可能清楚。
如果还有问题,请随时提问。
相关文章:
- 使用.find函数在c++中查找字符和另一个字符之间的大小
- 一个函数,用于查找字符串1包含字符串2 c++的次数
- 用于在 C++ 中使用 while 循环查找下一个素数的简单函数
- C++ 函数,用于查找传入的 N 个数字的平均值、总和、最小值和最大值
- 使用用户定义的函数查找数字的幂时出现问题
- 如何处理具有不同类的成员函数的函数查找表?
- 如果我们没有在 C++ 中传递大小变量,则通过函数查找数组的大小
- 使用用户定义的函数查找完美数时出现浮点异常错误
- 使用 lambda 函数查找 std::unordered_map 中的最小值
- 重载函数查找轮廓的实例与参数列表不匹配
- 使用C++中的割线函数查找根
- JNA 程序函数查找失败
- 通过 C 加加号中的函数查找中位数
- 试图通过函数查找数组的最大值和最小值,其中数组值由用户输入
- xlC模板函数问题的静态函数查找
- 使用线程函数查找 2D 数组中的最大条目
- 如何在cpp中使用std::regex_replace()函数查找和替换
- 数组函数查找最大值
- 使用' stdio.h '函数查找模板和名称
- CPP字符串构造函数查找并附加空字符