首页 > 编程语言 >C++11中的正则表达式

C++11中的正则表达式

时间:2024-04-03 14:56:43浏览次数:30  
标签:11 std search 匹配 正则表达式 C++ regex match

目录


regex

C++11 引入了 <regex> 头文件,它提供了对正则表达式的支持。这个库允许你编译、匹配和搜索正则表达式,以及使用正则表达式进行字符串替换。

以下是 C++11 中正则表达式库的一些关键组件:

  1. regex 类:表示一个正则表达式。你可以用它来编译一个正则表达式字符串,并之后用这个编译后的正则表达式进行匹配操作。

  2. regex_match 函数:用于确定一个整个字符串是否与一个正则表达式匹配。

  3. regex_search 函数:用于在一个字符串中搜索与正则表达式匹配的子串。

  4. regex_replace 函数:用于在字符串中替换与正则表达式匹配的子串。

  5. smatch 类:是一个特化的模板类,用于存储 regex_searchregex_match 的结果。它是一个 std::match_results<std::string::const_iterator> 的类型定义。

  6. regex_constants 命名空间:包含了一些用于指定正则表达式语法和匹配行为的标志。

下面是一个简单的例子,展示了如何在 C++11 中使用正则表达式:

#include <iostream>
#include <string>
#include <regex>

int main() {
    std::string s("Example string for regex matching.");
    std::regex e("regex"); // 正则表达式字面量

    // 使用 regex_search 查找匹配的子串
    if (std::regex_search(s, e)) {
        std::cout << "String contains 'regex'.\n";
    } else {
        std::cout << "String does not contain 'regex'.\n";
    }

    // 使用 regex_replace 替换匹配的子串
    std::string replaced = std::regex_replace(s, e, "pattern");
    std::cout << "Replaced string: " << replaced << std::endl;

    // 使用 smatch 存储匹配结果
    std::smatch match;
    if (std::regex_search(s, match, e)) {
        std::cout << "Match found: " << match.str() << std::endl;
    }

    return 0;
}

在这个例子中,我们首先创建了一个 std::regex 对象来表示正则表达式。然后,我们使用 std::regex_search 来检查字符串中是否包含与正则表达式匹配的子串。接着,我们使用 std::regex_replace 来替换匹配的子串。最后,我们使用 std::smatch 对象来存储 std::regex_search 的匹配结果,并打印出匹配的子串。


regex_match函数详解

regex_match 是 C++ 标准库 <regex> 中的一个函数,用于确定一个给定的整个字符串是否与一个正则表达式匹配。下面详细解释 regex_match 函数的工作原理和使用方法。

函数原型

<regex> 头文件中,regex_match 有几个重载版本,但最常用的是以下两个:

bool regex_match(const std::string& s, const std::regex& e);
bool regex_match(const std::string& s, std::smatch& m, const std::regex& e);
  • 第一个参数 s 是要进行匹配的输入字符串。
  • 第二个参数可以是 std::regex 对象 e,代表正则表达式,或者是 std::smatch 对象 m(或与 std::smatch 类似的类型),用于存储匹配的结果信息。当使用 std::smatch 时,它会包含整个匹配的信息以及任何分组(括号中的子匹配)。
  • 第三个参数总是 std::regex 对象 e,表示正则表达式。

函数返回一个布尔值,指示是否找到匹配。

使用方法

基本使用

#include <iostream>
#include <regex>
#include <string>

int main() {
    std::string s("12345");
    std::regex e("\\d+"); // 正则表达式,匹配一个或多个数字

    // 检查整个字符串是否与正则表达式匹配
    if (std::regex_match(s, e)) {
        std::cout << "The string matches the regular expression.\n";
    } else {
        std::cout << "The string does not match the regular expression.\n";
    }

    return 0;
}

在这个例子中,字符串 s 包含的是 "12345",它是一个由数字组成的字符串。正则表达式 e"\\d+",它匹配一个或多个数字。因此,regex_match 返回 true,表示整个字符串与正则表达式匹配。

使用 std::smatch 获取更多信息

std::smatch 是一个特殊的容器,用于保存 regex_matchregex_search 的结果。它可以让你访问匹配的子字符串以及它们在原字符串中的位置。

#include <iostream>
#include <regex>
#include <string>

int main() {
    std::string s("The quick brown fox");
    std::regex e("(.*) (brown) (.*)"); // 分组正则表达式
    std::smatch match;

    if (std::regex_match(s, match, e)) {
        std::cout << "Matched!\n";
        // 输出匹配的分组
        for (const auto& m : match) {
            std::cout << m << " ";
        }
        std::cout << "\n";
    } else {
        std::cout << "Not matched!\n";
    }

    return 0;
}

在这个例子中,我们使用了带有分组的正则表达式,并通过 std::smatch 接收匹配的结果。如果匹配成功,match 将包含整个匹配的字符串以及分组匹配的子字符串,我们可以遍历 match 来访问这些信息。

注意事项

  • regex_match 函数只会在整个输入字符串与正则表达式完全匹配时返回 true。如果你想要在字符串中搜索正则表达式的一部分,应该使用 regex_search
  • 使用复杂的正则表达式时,注意转义字符的使用。例如,在正则表达式字符串中,要匹配一个字面量反斜杠 \,你需要写作 "\\\\"
  • 正则表达式的编写和理解可能需要一些时间,特别是当涉及到更高级的功能如捕获组、零宽断言等时。有多种在线工具可以帮助你测试和调试正则表达式。

regex_search函数详解

regex_search 是 C++ 标准库 <regex> 中的一个非常有用的函数,用于在字符串中搜索与正则表达式匹配的子串。与 regex_match 不同,regex_search 不需要整个字符串与正则表达式完全匹配,只要找到任何匹配的子串,它就会返回成功。

函数原型

<regex> 头文件中,regex_search 的一些常见重载版本如下:

bool regex_search(const std::string& s, const std::regex& e);
bool regex_search(const std::string& s, std::smatch& m, const std::regex& e);
  • 第一个参数 s 是要进行搜索的输入字符串。
  • 第二个参数可以是 std::regex 对象 e,代表正则表达式,或者是 std::smatch 对象 m(或与 std::smatch 类似的类型),用于存储匹配结果的信息。当使用 std::smatch 时,它会包含匹配的子串以及任何分组(括号中的子匹配)。
  • 第三个参数总是 std::regex 对象 e,表示要搜索的正则表达式。

函数返回一个布尔值,指示是否在字符串中找到匹配的子串。

使用方法

基本使用

#include <iostream>
#include <regex>
#include <string>

int main() {
    std::string s("The price is 123 dollars.");
    std::regex e("\\d+"); // 正则表达式,匹配一个或多个数字

    // 在字符串中搜索与正则表达式匹配的子串
    if (std::regex_search(s, e)) {
        std::cout << "Found a match!\n";
    } else {
        std::cout << "No match found.\n";
    }

    return 0;
}

在这个例子中,regex_search 会在字符串 s 中搜索与正则表达式 e 匹配的子串。正则表达式 e"\\d+",它匹配一个或多个数字。因为字符串 s 包含 "123",所以 regex_search 返回 true

使用 std::smatch 获取匹配信息

std::smatch 对象可以保存 regex_search 的匹配结果,并提供对匹配的子串及其位置的访问。

#include <iostream>
#include <regex>
#include <string>

int main() {
    std::string s("Example: 123abc, 456def, 789ghi.");
    std::regex e("(\\d+)(\\w+)"); // 正则表达式,匹配数字和字母序列
    std::smatch match;

    if (std::regex_search(s, match, e)) {
        std::cout << "Found a match!\n";
        // 输出匹配的子串和分组
        for (size_t i = 0; i < match.size(); ++i) {
            std::cout << "Match " << i << ": " << match[i] << '\n';
        }
    } else {
        std::cout << "No match found.\n";
    }

    return 0;
}

在这个例子中,我们使用了分组正则表达式,并通过 std::smatch 接收匹配的结果。如果找到匹配项,match 将包含整个匹配的子串以及由括号定义的分组。我们可以通过索引访问 match 中的元素来获取这些信息。

注意事项

  • regex_search 函数只要找到第一个匹配的子串就会停止搜索,并返回成功。如果你想找到字符串中所有的匹配项,你需要使用循环,并在每次找到匹配项后更新搜索的起始位置。
  • regex_match 类似,编写复杂的正则表达式时需要注意转义字符的使用。
  • 如果你的正则表达式包含多个分组,std::smatch 将会包含相应数量的分组匹配结果,以及整个匹配的子串。std::smatch[0] 总是包含整个匹配的子串。

regex_search和regex_match的区别

regex_searchregex_match 是 C++11 <regex> 库中提供的两个用于正则表达式匹配的函数,它们之间有着关键的区别:

  1. 匹配范围

    • regex_match:这个函数试图将整个输入字符串与正则表达式进行匹配。只有当整个字符串完全符合正则表达式所定义的模式时,匹配才会成功。
    • regex_search:这个函数在输入字符串中搜索与正则表达式匹配的任何子串。它不需要整个字符串与正则表达式匹配,只要字符串中存在一个与正则表达式匹配的子串,搜索就会成功。
  2. 使用场景

    • 当你想要确认一个字符串是否完全由一个特定的模式组成时,你会使用 regex_match。例如,验证一个字符串是否为有效的电子邮件地址或电话号码。
    • 当你想要在一个较大的文本块中查找符合特定模式的子串时,你会使用 regex_search。例如,在文章中查找所有的日期或电话号码实例。
  3. 返回值

    • 两个函数都返回一个布尔值,指示是否找到了匹配项。对于 regex_match,如果整个字符串匹配,则返回 true;对于 regex_search,如果在字符串中找到匹配的子串,则返回 true
  4. 结果处理

    • 当与 smatch(或类似的匹配结果类)一起使用时,regex_search 可以提供关于匹配子串的更多信息,如其在字符串中的位置和长度。regex_match 也可以与这些类一起使用,但由于它匹配整个字符串,所以匹配结果通常不那么复杂。

下面是一个简单的代码示例,说明了 regex_searchregex_match 之间的区别:

#include <iostream>
#include <string>
#include <regex>

int main() {
    std::string s("123abc456");
    std::regex e("\\d+"); // 匹配一个或多个数字

    // 使用 regex_match 尝试匹配整个字符串
    if (std::regex_match(s, e)) {
        std::cout << "The entire string is a match.\n";
    } else {
        std::cout << "The entire string is not a match.\n"; // 这将被执行
    }

    // 使用 regex_search 查找匹配的子串
    if (std::regex_search(s, e)) {
        std::cout << "A substring is a match.\n"; // 这将被执行
    } else {
        std::cout << "No substring is a match.\n";
    }

    return 0;
}

在这个例子中,regex_match 失败,因为整个字符串 s 不完全由数字组成。然而,regex_search 成功,因为字符串 s 中包含与正则表达式 e 匹配的子串(即 "123""456")。

标签:11,std,search,匹配,正则表达式,C++,regex,match
From: https://www.cnblogs.com/yubo-guan/p/18112692

相关文章

  • 该升级了!Windows 11 24H2要来了:支持USB4、Wi-Fi 7等
    如果你一直在期待可以升级的Windows11,那么好消息来了。据国外媒体报道称,微软正式确认了Windows1124H2,将其定名为Windows11的"2024更新",预计将在今年9月和10月期间全面推出。报道称,Windows1124H2将于本月进入RTM阶段,而首批基于Arm架构的AIPC将在接下来几个月的6月亮相。......
  • 关于Win11系统 Ixchariot打流出现上行流无法打通的情况
    电脑有线接入,手机无线连接测试设备Wi-Fi,IxChariot链路从电脑IP到手机IP,可以打通。但是反过来无法进行。Win11电脑安装IxChariot(版本为6.70版本)时,安装的IXCHARIOTENDPOINTARCHIVE报错,无法安装:Error1920.SericeIxiaPerformanceEndpoint(IxiaEndpoint)failedtostart. 需......
  • 【C/C++】VsCode调试配置tasks.json和launch.json
    前段时间配大作业环境改了很多配置,发现tasks.json和launch.json经常令自己很迷惑。网上找的配置有时会有各种各样的问题,在此记录一下上学期配好的配置文件,日后有时间再详细研究研究tasks.json:{"version":"2.0.0","tasks":[{"type":"shell",......
  • [c++] 小游戏 斗破苍穹2.7.1 版本 zty出品
    前言大家好,今天带来的是经典版本2.7.1这个版本在斗破苍穹中十分重要您好,欢迎您玩苍穹世界。为了给您更好的游戏体验,zty时不时会优化本游戏,优化后会尽快发布在网上。关于外挂方面,开启外挂的方式是设定勇者姓名时,输入“zty”(不包括双引号)。由于2.6.1版本的bug,我们在2.6.1的......
  • K11998 括号画家
    题目描述小科是一名漫画家,他有一个奇特的爱好,就是在纸上画括号。这一天,刚刚起床的他画了一排括号序列,其中包含小括号()、中括号[]和大括号{},总长度为N。这排随意绘制的括号序列显得杂乱无章,于是小科定义了什么样的括号序列是美观的:①空的括号序列是美观的;②若括号序列A是......
  • 【华为OD】2024年华为OD机试C卷真题集:最新的真题集题库 C/C++/Java/python/JavaScript
    【华为OD】2024年C卷真题集:最新的真题集题库C/C++/Java/python/JavaScript【华为OD】2024年C卷真题集:最新的真题集题库C/C++/Java/python/JavaScript-CSDN博客 2024年华为OD机试C卷真题题集题库,有2种分数的题目列表分别是100分的列表、200分的列表需要订阅请看链接:C卷......
  • C/C++的部分笔记
    C/C++部分笔记1、纯虚函数纯虚函数是一种特殊的虚函数,基类定义后(~=0)必须由派生类重写,纯虚函数将父类上升为一个抽象类,无法实例化对象;抽象类是指具有纯虚函数的类;一个基类说明有纯虚函数,该基类的派生类可以是抽象类;抽象类只能作为基类来使用,其纯虚函数的实现由派生类给出。......
  • Win11下更好用的截图工具
    Win11下更好用的截图工具使用PixPin(推荐)优先建议使用PixPin,功能更加丰富,而且不需要在手动处理快捷键了下载链接PixPin_1.7.6.0.exe​​​​这样子就完成了,不需要再使用后续的2,3了FlameShot原生的截图工具功能不是特别丰富,现在使用flameshot​来替代他如......
  • 【C++】入门知识
    1.命名空间在C/C++中,变量、函数和后面要学到的类都是大量存在的,这些变量、函数和类的名称都将存在于全局作用域中,可能会导致很多冲突。使用命名空间的目的就是对标识符的名称进行本地化,以避免命名冲突或名字污染,namespace关键字的出现就是针对这种问题的。#include<iostre......
  • 【C/C++】计时模版
    C++autostart=chrono::system_clock::now();/*dosomething*/autoend=chrono::system_clock::now();chrono::duration<double>diff=end-start;cout<<"Elapsedtime:"<<diff.count()<<"sec.\n";很现代化的一......