C++正则表达式获取指定数字

楼主在近期遇到一个小需求,需要从版本号字符串“a.b.c.d”中获取a、b、c、d,代码内容如下:

std::string version = "1.1.1.4";
std::regex pattern(R"(^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)$)");
\\R的作用是原始字符串字面量,告诉编译器括号内的内容应按字面意义解析,如果没有的话,需要\\d与\\.
\\0|[1-9]\d*作用是检查0或1-9的所有数字,支持0、12等数字,不支持01、012等数字
\\^与$标志着正则表达式的开始与结束
std::smatch matches;
std::vector<uint32_t> version_num;
if(std::regex_match(version, matches, pattern))
{
    for(uint idx = 0; idx < matches.size(); ++idx)
    {
        \\std::regex_match处理后得到的matches还是字符串,需要转为uint32_t使用
        std::stringstream ss(matches[idx].str());
        uint32_t num;
        ss >> num;
        version_num.push_back(num);
    }
}

<think>我们正在处理用户的问题:如何在C++中使用正则表达式进行任意字符或子串的匹配。 根据引用[1],我们知道C++正则表达式库在<regex>头文件中,提供了多种函数和类。 用户特别询问了“匹配任意字符或子串”的方法,这通常涉及到正则表达式的模式编写。 在正则表达式中: - 点号 '.' 可以匹配任意单个字符(除了换行符,除非指定特殊标志)。 - 如果要匹配任意多个字符(包括零个),可以使用 '.*',其中 '*' 表示零次或多次。 - 如果要匹配一个特定的子串,可以直接写出该子串。 在C++中,我们可以使用regex_search函数来查找字符串中是否存在与正则表达式匹配的子串(部分匹配),或者使用regex_match来检查整个字符串是否完全匹配。 根据引用[1]: regex_match: 要求整个字符序列与正则表达式匹配 regex_search: 在字符序列中查找一个与正则表达式匹配的子序列,找到第一个就停止 因此,如果用户想要匹配任意子串(即部分匹配),应该使用regex_search。 另外,引用[2]中给出了一个正则表达式匹配的算法实现,但那是解决一个特定问题(支持'.'和'*'的正则表达式匹配),我们可以直接使用C++标准库中的正则表达式功能,而不需要自己实现。 下面我们给出一个示例,展示如何使用C++正则表达式来匹配任意字符或子串。 注意:在正则表达式中,如果要匹配的字符本身是正则表达式的元字符(如. * + ? ^ $ | \ ( ) [ ] { }),则需要转义。但如果是普通字符串,则直接写即可。 示例1:匹配任意单个字符(使用'.') 示例2:匹配任意子串(使用'.*',表示任意长度的任意字符序列) 示例3:匹配一个特定的子串(直接写子串) 我们分别用regex_search和regex_match来演示。 由于用户问题中提到了“任意一节匹配”,我理解为部分匹配(即子串匹配),所以重点使用regex_search。 步骤: 1. 包含头文件<regex> 2. 定义正则表达式模式字符串 3. 使用regex类编译正则表达式(可以指定标志,如忽略大小写等) 4. 使用regex_search函数进行匹配 代码示例: */ #include <iostream> #include <regex> #include <string> int main() { std::string str = "Hello, world! This is a test string."; // 示例1:匹配任意单个字符(这里我们匹配一个任意字符后跟一个字母'o') std::regex pattern1(".o"); // 会匹配 "lo", "wo", "ro" 等 std::smatch matches; std::cout << "匹配任意单个字符后跟'o':" << std::endl; if (std::regex_search(str, matches, pattern1)) { for (size_t i = 0; i < matches.size(); ++i) { std::cout << "找到匹配: " << matches[i] << std::endl; } } // 示例2:匹配任意子串(这里我们匹配"world"后面跟着任意字符直到"test") std::regex pattern2("world.*test"); // .* 表示任意数量的任意字符(贪婪匹配) std::cout << "\n匹配子串'world.*test':" << std::endl; if (std::regex_search(str, matches, pattern2)) { std::cout << "找到匹配: " << matches[0] << std::endl; } // 示例3:匹配一个特定的子串(直接写) std::regex pattern3("test"); std::cout << "\n匹配特定子串'test':" << std::endl; if (std::regex_search(str, matches, pattern3)) { std::cout << "找到匹配: " << matches[0] << std::endl; } // 注意:regex_search每次只找第一个匹配,如果要找所有匹配,可以使用sregex_iterator(如引用[1]所述) std::cout << "\n使用迭代器查找所有'test'或'is':" << std::endl; std::regex pattern4("(test|is)"); auto words_begin = std::sregex_iterator(str.begin(), str.end(), pattern4); auto words_end = std::sregex_iterator(); for (std::sregex_iterator i = words_begin; i != words_end; ++i) { std::smatch match = *i; std::cout << match.str() << std::endl; } return 0; } /* 注意: - 在模式字符串中,我们使用了双反斜杠(在C++字符串中,反斜杠需要转义)来表示正则表达式中的转义。例如,要匹配一个实际的点号(而不是任意字符),应使用"\\."。 - 如果正则表达式模式在程序运行前已知,最好使用std::regex的构造函数一次编译,避免重复编译的开销。 - 如果正则表达式无效,构造函数会抛出std::regex_error异常,需要进行异常处理。 另外,关于任意字符的匹配,默认情况下,点号不匹配换行符。如果需要匹配包括换行符在内的任意字符,可以使用标志std::regex_constants::syntax_option_type中的dotall(在C++中,可以通过在构造正则表达式指定标志来启用,例如:std::regex pattern(".*", std::regex::dotall);)。 总结: 在C++中,使用<regex>库进行正则表达式匹配,匹配任意字符使用点号'.',匹配任意子串使用'.*'(贪婪匹配)或'.*?'(非贪婪匹配,但C++默认不支持非贪婪,需要使用ECMAScript语法中的惰性量词,即在*后面加?,如".*?")。对于部分匹配(子串),使用regex_search函数;对于整个字符串的匹配,使用regex_match。 最后,根据用户的问题,我们主要展示了regex_search的用法,因为它适用于子串匹配(任意一节匹配)。 */ §§相关问题§§ 1. C++正则表达式中如何匹配包括换行符的任意字符? 2. regex_search和regex_match有什么区别? 3. 在C++中如何匹配一个特定的单词(而不是作为子字符串的一部分)?</think>在 C++ 中使用正则表达式进行任意字符或子串匹配,主要通过 `<regex>` 库实现。以下是关键方法和示例: ### 1. **匹配任意字符** - **`.`** 表示匹配任意单个字符(换行符 `\n` 除外) - **`.*`** 表示匹配任意长度字符序列(贪婪匹配) - **`.*?`** 表示非贪婪匹配(最短匹配) ```cpp #include <regex> #include <string> #include <iostream> int main() { std::string text = "abc123xyz"; std::regex pattern("c.*x"); // 匹配 "c" 开头、"x" 结尾的任意子串 std::smatch matches; if (std::regex_search(text, matches, pattern)) { std::cout << "匹配结果: " << matches[0] << std::endl; // 输出 "c123x" } return 0; } ``` ### 2. **匹配特定子串** - 直接写入子串内容(支持正则元字符转义): ```cpp std::regex pattern("\\d+"); // 匹配连续数字,如 "123" ``` ### 3. **关键函数** - **`std::regex_search`**:搜索**部分匹配**(子串),找到即停止[^1]。 - **`std::regex_match`**:要求**整个字符串**完全匹配[^1]。 - **`std::smatch`**:存储匹配结果(如 `matches[0]` 获取完整匹配)。 ### 4. **匹配所有子串(迭代器)** ```cpp std::string text = "test1 test2 test3"; std::regex pattern("test\\d"); // 匹配 "test+数字" auto begin = std::sregex_iterator(text.begin(), text.end(), pattern); auto end = std::sregex_iterator(); for (auto it = begin; it != end; ++it) { std::cout << "找到: " << it->str() << std::endl; // 输出 "test1", "test2", "test3" } ``` ### 5. **特殊字符转义** - 使用 `\\` 转义正则元字符(如 `*`, `.`, `?`): ```cpp std::regex pattern("a\\.b"); // 匹配字面值 "a.b" ``` ### 6. **匹配模式标志** - 控制匹配行为(如忽略大小写、跨行匹配): ```cpp std::regex pattern("a.*b", std::regex_constants::icase); // 忽略大小写 ``` ### 常见问题解答 - **匹配任意字符包括换行符**: 使用 `std::regex::dotall` 标志(或 `(?s)` 模式): ```cpp std::regex pattern("a.*b", std::regex_constants::dotall); ``` - **性能注意**: 多次使用同一正则表达式时,复用 `std::regex` 对象避免重复编译。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值