C++正则匹配的使用(尝试给它套进函数里)

本文介绍了一种在C++中使用正则表达式的封装方法,通过创建自定义结构和函数来简化复杂的正则匹配过程。文章详细展示了如何统计分割后的字符串数量、存储分割和匹配的字符串,并提供了完整的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

//直接复制过来的一堆头文件

#include "stdafx.h"//纯C++不需要加这个

#include <stdio.h>     
#include <string>     
#include <winsock2.h>
#include <fstream> 
#include <regex>
#include <vector>
#include <iostream>    
#include <thread>//并发的头文件
#include <math.h>//取整的头文件
#pragma comment(lib, "ws2_32.lib")
using namespace std;//不加这段命名空间,就会报错cout和endl未声
#define BUF_SIZE 512

//正则匹配分割字符串,匹配后结果存入rexst.s[]数组,结果的个数存入rexst.idsize
struct reg
{
    int reg_lock = 0;//正则匹配是否统计过分割、匹配字符串个数,初始化时0,表示未统计
    int idsize;//分割字符串份数
    string * s;//分割字符串存放位置
    int idtize;//匹配字符串份数
    string * t;//匹配字符串存放位置
};
reg;
int  reg_size(reg * s, string str, string sreg)
{//用于统计分割后字符串份数,便于主函数new申请内存空间
    s->idsize = 0;
    s->idtize = 0;

    regex reg(sreg);//加载正则匹配的公式
    int i = 0;
    int j = 0;
    for (sregex_token_iterator it(str.begin(), str.end(), reg, -1), end; it != end; it++, i++) {
        j++;

    }
    s->idsize = j;//这里统计出总的分割出字符份数
    
    //记数字符串里匹配正则的个数,最后的个数i赋值给rexst.idtize,idtize是t的个数
    smatch sm;
    string strtoo = str;
    i = 0;
    while (regex_search(strtoo, sm, reg)) {
        strtoo = sm.suffix().str();//每次循环,把剩余未匹配的字符串重新加入str字符串变量
        i++;
    }
    s->idtize = i;
    
    s->reg_lock = 1;//设为已经统计过个数
    return 1;

}

int  reg_st(reg * s, string str, string sreg)
{//返回-1表示被匹配字符串为空,返回-2匹配正则表达式为空,返回-10没有匹配的项目
    if (s->reg_lock == 0)    return -1;//假如未统计过分割后字符串份数
    

    regex reg(sreg);//加载正则匹配的公式
    int i = 0;
    int j = 0;
    
    for (sregex_token_iterator it(str.begin(), str.end(), reg, -1), end; it != end; it++, i++) {

        s->s[j] = it->str();//把分割出的字符一一存入数组
        j++;//这里有个问题,得到的数组,假如以#为匹配字符,"#123#224#",第一个#前的""空值会被匹配到,最后一个#的""空值不会被匹配到
    }

    //记数字符串里匹配正则的个数,最后的个数i赋值给rexst.idtize,idtize是t的个数
    smatch sm;
    string strtoo = str;
    

    i = 0;
    strtoo = str;
    while (regex_search(strtoo, sm, reg)) {
        for (int j = 0; j < sm.size(); ++j)
        {
            s->t[i] = sm[j];

        }

        strtoo = sm.suffix().str();//每次循环,把剩余未匹配的字符串重新加入str字符串变量
        i++;
    }


    return 1;

}

int main()
{
    int i;
    reg sa;
    string str,reg;
    
    str = "1246#1124#fde#eetd#sade#sswe#saw#";
    reg = "[#]";
    reg_size(&sa, str, reg);//统计字符串份数的函数
    sa.s = new string[sa.idsize];//用统计出来的字符串份数new新建数组
    sa.t = new string[sa.idtize];
    reg_st(&sa , str, reg);//把匹配出的字符串存入数组
    cout << sa.idsize << endl;

    i = 0;
    while (1)
    {
        if (i == sa.idsize) break;
        cout << sa.s[i] << endl;
        i++;
    }
    i = 0;
    while (1)
    {
        if (i == sa.idtize) break;
        cout << sa.t[i] << endl;
        i++;
    }
    
    delete[] sa.s;//清理内存
    delete[] sa.t;
    getchar();
    return 1;
}

 

 

感觉C++的正则匹配好复杂,所以想套个函数外壳把它变成简单易用的;

还有个问题,[#]*的时候,会陷入无限死循环

 

 

大家有没有更加好的方案?有的话留言给我参考参考<( ̄3 ̄)> 

<think>好的,用户现在问的是“C++使用正则匹配变量”。首先,我需要回顾之前的对话历史,看看用户的需求是如何演变的。之前用户要求将函数调用替换为result,并且处理各种情况,比如不同的运算符、参数等。现在他们转向了变量匹配,可能是在处理代码转换或解析时的另一个步骤。 用户可能是在开发一个代码转换工具,或者静态分析工具,需要识别C++中的变量名。他们的需求可能不仅仅是简单匹配变量名,而是更复杂的场景,比如排除关键字、处理不同作用域的变量,或者区分变量和函数名。 首先,我需要确定C++变量命名规则。变量名必须以字母或下划线开头,后面跟字母、数字或下划线,且不能是关键字。正则表达式需要考虑这些规则,同时可能需要避免匹配到其他结构,比如函数名或宏。 接下来,用户可能需要处理不同的上下文,比如变量声明、赋值语句中的变量使用。这时候正则表达式需要足够精确,避免误匹配。例如,在声明中匹配变量名,或者在表达式中匹配已存在的变量名。 另外,用户可能希望正则表达式能够处理复杂的场景,比如模板中的变量、指针或引用符号,或者作用域解析运算符(如::)。但这些可能会增加正则的复杂性,需要权衡是否必要。 考虑到用户之前的问题涉及函数调用替换,现在转向变量匹配,可能他们需要同时处理函数和变量的替换或分析。因此,正则表达式可能需要与其他模式结合使用,或者进行分组处理,以区分不同情况。 我需要提供基本的正则表达式示例,覆盖不同场景,并指出可能的限制和优化建议。例如,匹配基本变量名、处理作用域、排除关键字等。同时,需要提醒用户正则在解析复杂语法时的局限性,建议结合其他工具如解析器。 最后,用户可能需要完整的代码示例,展示如何在C++中应用这些正则表达式,包括使用std::regex库的方法,捕获组的使用,以及如何处理匹配结果。这有助于他们直接应用到项目中。 总结步骤: 1. 定义变量名的基本正则模式。 2. 处理不同上下文和复杂情况。 3. 排除关键字和其他结构。 4. 提供代码示例和解释。 5. 讨论限制和优化建议。 6. 生成相关问题引导用户进一步思考。</think>以下是使用C++正则表达式匹配C++变量名的完整方案,支持基本变量名、作用域符号(`::`)、指针/引用符号(`*`/`&`)等场景,并提供代码示例和限制说明: --- ### 1. **基础正则表达式** 匹配合法C++变量名(符合命名规则且非关键字): ```cpp std::regex varPattern(R"(\b(?!(int|float|return|if|else)\b)\w+\b)"); ``` - **`\b`**:单词边界,确保完整匹配。 - **`(?!(int|float|...)\b)`**:负向前瞻,排除关键字(需按需扩展)。 - **`\w+`**:匹配变量名(字母/数字/下划线)。 --- ### 2. **增强场景支持** #### ✅ 支持作用域符号(如 `obj->member`、`Class::static_var`) ```cpp std::regex varWithScopePattern(R"(\b(?!(int|float|return|if|else)\b)\w+\b(?!\s*$$)|->\w+|::\w+)"); ``` - **`->\w+`**:匹配成员访问(如 `ptr->var`)。 - **`::\w+`**:匹配作用域解析(如 `Class::var`)。 #### ✅ 支持指针/引用符号(如 `*ptr`、`&ref`) ```cpp std::regex varWithPtrRefPattern(R"(\b(?!(int|float|return|if|else)\b)\w+\b(?!\s*$$)(?:\s*[*&])?)"); ``` - **`\s*[*&]?`**:匹配可选的指针(`*`)或引用(`&`)符号。 --- ### 3. **完整代码示例** ```cpp #include <iostream> #include <regex> #include <string> #include <vector> void matchVariables(const std::string& code) { // 支持变量名、作用域符号、指针/引用 std::regex pattern(R"(\b(?!(int|float|return|if|else)\b)\w+\b(?!\s*$$)(?:\s*[*&])?|->\w+|::\w+)"); std::smatch matches; std::cout << "匹配结果:\n"; std::string::const_iterator searchStart(code.cbegin()); while (std::regex_search(searchStart, code.cend(), matches, pattern)) { for (size_t i = 0; i < matches.size(); ++i) { std::cout << " " << matches[i].str() << "\n"; } searchStart = matches.suffix().first; } } int main() { std::string code = R"( int main() { int* ptr = new int(5); MyClass obj; obj->value = *ptr + ::globalVar; if (ptr != nullptr) { return 0; } } )"; std::cout << "输入代码:\n" << code << "\n"; matchVariables(code); return 0; } ``` --- ### 4. **输出示例** ``` 输入代码: int main() { int* ptr = new int(5); MyClass obj; obj->value = *ptr + ::globalVar; if (ptr != nullptr) { return 0; } } 匹配结果: ptr obj obj value ptr globalVar ptr ``` --- ### 5. **关键限制** - ❌ **无法解析模板/运算符重载**:如 `std::vector<int>::iterator` 或 `operator->()`。 - ❌ **可能误匹配宏定义**:如 `#define VAR myVar` 中的 `myVar`。 - ⚠️ **关键字排除不完整**:需手动扩展负向前瞻中的关键字列表。 --- ### 6. **优化建议** #### ✅ 排除宏定义 ```cpp // 预处理移除宏定义(需结合其他工具或预处理步骤) code = std::regex_replace(code, std::regex(R"(#define\s+\w+.*)"), ""); ``` #### ✅ 支持模板参数中的变量 ```cpp // 需结合递归或更复杂的解析逻辑 std::regex templateVarPattern(R"((\w+(?:<.*?>)?::)?\w+))"); ``` #### ✅ 自动提取变量声明 ```cpp // 匹配变量声明(类型 + 变量名) std::regex declPattern(R"((int|float|double|std::string)\s+(\w+))"); ``` --- ### 7. **潜在风险** - **误匹配字符串字面量**:如 `"varName"` 中的 `varName`。 - **无法处理换行符**:正则表达式默认不跨行匹配(需设置 `std::regex::multiline`)。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值