C++ 11 正则表达式

C++11正则表达式 正则表达式是一种文本模式,包括普通字符(例如,a 到 z 之间的字母)和特殊字符(称为"元字符")。正则表达式使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串。 头文件: #include <regex> 1、regex_match:整个字符串是否匹配 2、regex_search:只返回第一个匹配结果 3、iterator:返回多个匹配结果,类似于指针,调用成员要... 阅读详情

我对C处理字符串学习得非常少,之前最多使用过strtok函数来split字符串。每次处理文本的时候都是使用的通过python来做处理。上次看同事使用做多语言版本的时候,使用C++ 11 标准编写了一个程序,去分析全部的代码里面的中文字串,列出一个清单写到excel。说明C++也是能做这样类似的处理了。本文将通过读手册来学习C++ 11 regular expression。

手册

手册

objects

定义文件:

#include <regex>

几乎全部正则操作能被归类于对于下面对象的操作:

target sequence

目标序列,就是提供出来给正则来处理的字符串。可能是一个指定了iterators区间、一个null结束的字符串,或者是std::string

Pattern

模式:就是正则表达式本身。
c++ 11 正则语法选项

Matched array

匹配队列:匹配信息可能被转换成一个std::match_results类型的对象。

Replacement string

这个字符串决定了如何替掉匹配的字符串。

Main classes

basic_regex

正则表达式对象。
窄字节、宽字节的支持:

TypeDefinition
regexbasic_regex
wregexbasic_regex

flag_type:可以定制正则表达式对象做一些定制。定制文档
这里主要是定制正则表达式的一些选项。

ValueEffect(s)
icaseCharacter matching should be performed without regard to case.
nosubsWhen performing matches, all marked sub-expressions (expr) are treated as non-marking sub-expressions (?:expr). No matches are stored in the supplied std::regex_match structure and mark_count() is zero
optimizeInstructs the regular expression engine to make matching faster, with the potential cost of making construction slower. For example, this might mean converting a non-deterministic FSA to a deterministic FSA.
collateCharacter ranges of the form “[a-b]” will be locale sensitive.
ECMAScriptUse the Modified ECMAScript regular expression grammar
basicUse the basic POSIX regular expression grammar (grammar documentation).
extendedUse the extended POSIX regular expression grammar (grammar documentation).
awkUse the regular expression grammar used by the awk utility in POSIX (grammar documentation)
grepUse the regular expression grammar used by the grep utility in POSIX. This is effectively the same as the basic option with the addition of newline ‘\n’ as an alternation separator.
egrepUse the regular expression grammar used by the grep utility, with the -E option, in POSIX. This is effectively the same as the extended option with the addition of newline ‘\n’ as an alternation separator in addtion to ‘|’.

举个例子:

std::regex("meow", std::regex::icase)

sub_match

定义被子表达式匹配的字符序列

match_results

定义一个正则匹配结果,包含全部的子表达式匹配结果。

Algorithms

regex_match

match是做一次匹配。

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

int main()
{
    // Simple regular expression matching
    std::string fnames[] = {"foo.txt", "bar.txt", "baz.dat", "zoidberg"};
    std::regex txt_regex("[a-z]+\\.txt");

    for (const auto &fname : fnames) {
        std::cout << fname << ": " << std::regex_match(fname, txt_regex) << '\n';
    }   

    // Extraction of a sub-match
    std::regex base_regex("([a-z]+)\\.txt");
    std::smatch base_match;

    for (const auto &fname : fnames) {
        if (std::regex_match(fname, base_match, base_regex)) {
            // The first sub_match is the whole string; the next
            // sub_match is the first parenthesized expression.
            if (base_match.size() == 2) {
                std::ssub_match base_sub_match = base_match[1];
                std::string base = base_sub_match.str();
                std::cout << fname << " has a base of " << base << '\n';
            }
        }
    }

    // Extraction of several sub-matches
    std::regex pieces_regex("([a-z]+)\\.([a-z]+)");
    std::smatch pieces_match;

    for (const auto &fname : fnames) {
        if (std::regex_match(fname, pieces_match, pieces_regex)) {
            std::cout << fname << '\n';
            for (size_t i = 0; i < pieces_match.size(); ++i) {
                std::ssub_match sub_match = pieces_match[i];
                std::string piece = sub_match.str();
                std::cout << "  submatch " << i << ": " << piece << '\n';
            }   
        }   
    }   
}

例子演示了如何通过sub_match将一次match出来的内容分组读取出来。

foo.txt: 1
bar.txt: 1
baz.dat: 0
zoidberg: 0
foo.txt has a base of foo
bar.txt has a base of bar
foo.txt
  submatch 0: foo.txt
  submatch 1: foo
  submatch 2: txt
bar.txt
  submatch 0: bar.txt
  submatch 1: bar
  submatch 2: txt
baz.dat
  submatch 0: baz.dat
  submatch 1: baz
  submatch 2: dat

regex_search

search是可以迭代将全部匹配的找出来。

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

int main()
{
    std::string lines[] = {"Roses are #ff0000",
                           "violets are #0000ff",
                           "all of my base are belong to you"};

    std::regex color_regex("#([a-f0-9]{2})"
                            "([a-f0-9]{2})"
                            "([a-f0-9]{2})");

    // simple match
    for (const auto &line : lines) {
        std::cout << line << ": " << std::boolalpha
                  << std::regex_search(line, color_regex) << '\n';
    }   
    std::cout << '\n';

    // show contents of marked subexpressions within each match
    std::smatch color_match;
    for (const auto& line : lines) {
        if(std::regex_search(line, color_match, color_regex)) {
            std::cout << "matches for '" << line << "'\n";
            std::cout << "Prefix: '" << color_match.prefix() << "'\n";
            for (size_t i = 0; i < color_match.size(); ++i) 
                std::cout << i << ": " << color_match[i] << '\n';
            std::cout << "Suffix: '" << color_match.suffix() << "\'\n\n";
        }
    }

    // repeated search (see also std::regex_iterator)
    std::string log(R"(
        Speed:  366
        Mass:   35
        Speed:  378
        Mass:   32
        Speed:  400
    Mass:   30)");
    std::regex r(R"(Speed:\t\d*)");
    std::smatch sm;
    while(regex_search(log, sm, r))
    {
        std::cout << sm.str() << '\n';
        log = sm.suffix();
    }
}

Output:

Roses are #ff0000: true
violets are #0000ff: true
all of my base are belong to you: false

matches for 'Roses are #ff0000'
Prefix: 'Roses are '
0: #ff0000
1: ff
2: 00
3: 00
Suffix: ''

matches for 'violets are #0000ff'
Prefix: 'violets are '
0: #0000ff
1: 00
2: 00
3: ff
Suffix: ''

Speed:  366
Speed:  378
Speed:  400

regex_replace

查找匹配到的字符并且替换。这个也支持常用的抓取替换的写法。

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

int main()
{
   std::string text = "Quick brown fox";
   std::regex vowel_re("a|e|i|o|u");

   // write the results to an output iterator
   std::regex_replace(std::ostreambuf_iterator<char>(std::cout),
                      text.begin(), text.end(), vowel_re, "*");

   // construct a string holding the results
   std::cout << '\n' << std::regex_replace(text, vowel_re, "[$&]") << '\n';
}

output

Q**ck br*wn f*x
Q[u][i]ck br[o]wn f[o]x
void auto_test2()
{
    std::string erl_text = "-define(CMD_CONNECT_EXCHANGE_KEY_REQ, 3).";
    std::regex match_erl_define("-define\\(([a-zA-Z_]+), ([0-9]+)\\)\\.");

    // construct a string holding the results
    std::cout << '\n' << std::regex_replace(erl_text, match_erl_define, "#define $1 $2") << '\n';
}

输出:

#define CMD_CONNECT_EXCHANGE_KEY_REQ 3

全面了解正则内建的替换字符串表意可以查看这个手册

RegExp.lastMatch
RegExp['$&']
RegExp.$1-$9
RegExp.input ($_)
RegExp.lastParen ($+)
RegExp.leftContext ($`)
RegExp.rightContext ($')

注意在c++里面写正则的时候,需要写\来做转义符号。而且中间()这种catch都是直接支持的。
匹配的时候*,+都不需要转义。{2}这种限定出现次数的符号也不需要转义。
在wiki里面叫做:Quantification

fmt - the regex replacement format string, exact syntax depends on the value of flags

Iterators

迭代器

regex_iterator

可以迭代方式去查询正则表达式匹配到的内容,这个是用的场景应该是当需要在查找过程中控制次数的情况。打个比方,一段文字,里面写了某个酒店里面客人消费数目,你想通过正则抓取出当酒店收到消费额度到100块的时候,这些消费的客人清单,就可以用这个来做。当循环到发现数目已经到了100块就可以结束掉正则匹配。而不是将全部的清单匹配出来,然后一条条过,最后用前面几条。

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

int main()
{
    const std::string s = "Quick brown fox.";

    std::regex words_regex("[^\\s]+");
    auto words_begin = 
        std::sregex_iterator(s.begin(), s.end(), words_regex);
    auto words_end = std::sregex_iterator();

    std::cout << "Found " 
              << std::distance(words_begin, words_end) 
              << " words:\n";

    for (std::sregex_iterator i = words_begin; i != words_end; ++i) {
        std::smatch match = *i;                                                 
        std::string match_str = match.str(); 
        std::cout << match_str << '\n';
    }   
}

输出内容:

Found 3 words:
Quick
brown
fox.

regex_token_iterator

#include <fstream>
#include <iostream>
#include <algorithm>
#include <iterator>
#include <regex>

int main()
{
   std::string text = "Quick brown fox.";
   // tokenization (non-matched fragments)
   // Note that regex is matched only two times: when the third value is obtained
   // the iterator is a suffix iterator.
   std::regex ws_re("\\s+"); // whitespace
   std::copy( std::sregex_token_iterator(text.begin(), text.end(), ws_re, -1),
              std::sregex_token_iterator(),
              std::ostream_iterator<std::string>(std::cout, "\n"));

   // iterating the first submatches
   std::string html = "<p><a href=\"http://google.com\">google</a> "
                      "< a HREF =\"http://cppreference.com\">cppreference</a>\n</p>";
   std::regex url_re("<\\s*A\\s+[^>]*href\\s*=\\s*\"([^\"]*)\"", std::regex::icase);
   std::copy( std::sregex_token_iterator(html.begin(), html.end(), url_re, 1),
              std::sregex_token_iterator(),
              std::ostream_iterator<std::string>(std::cout, "\n"));
}

关于两者的区别在于,token可以在查找的时候可以定制submatches。
实例1
实例2

Exceptions

regex_error

抓取正则的错误。

#include <regex>
#include <iostream>

int main()
{
    try {
        std::regex re("[a-b][a");
    } 

    catch (const std::regex_error& e) {
        std::cout << "regex_error caught: " << e.what() << '\n';
        if (e.code() == std::regex_constants::error_brack) {
            std::cout << "The code was error_brack\n";
        }
    }
}
regex_error caught: The expression contained mismatched [ and ].
The code was error_brack

总结

基本上看完这些东西,使用c++来做一些匹配上的工作了。

void test_chinese_re()
{
    string text = "vice jax teemo, 老张  武松 ";
    regex reg(" ([\u4e00-\u9fa5]+) ");

    sregex_iterator pos(text.cbegin(), text.cend(), reg);
    sregex_iterator end;
    for (; pos != end; ++pos) {
        cout << "match:  " << pos->str() << endl;
        cout << " tag:   " << pos->str(1) << endl;
    }

}
match:   老张
 tag:   老张
match:   武松
 tag:   武松
std::regex匹配正则表达式C++11 C++11中引入的这个正则表达式解析的还是挺好用的。 代码 unpack_call 的目的是将input拆分出name和value的值。 这个例子没什么用,就看看效果就好 例子:name: hello ; value: world 打印输出: name: hello ; value: world hello world #include <regex> static bool diag_call(const std::string& input) { // s 是匹配空格. 阅读详情

相关推荐

Windows下Colmap编译安装全攻略:从Boost到CUDA的避坑指南

本文详细介绍了在Windows系统下编译安装Colmap三维重建工具的完整流程与实战经验。针对Boost库版本兼容性、CUDA与Visual Studio的版本匹配等常见难题提供了具体的避坑指南和解决方案,帮助开发者高效完成从环境配置到最终部署的全过程。

weixin_28235513的博客 198

Regex - C++11, 6 of n

1) Raw string R"delim(...)delim", where delim is a character sequence of at most 16 basic characters except the backslash, whitespace and parentheses. 2) Note regex algorithm is greedy 3) Main in

CPP_CHEN的专栏 4788

半监督的医学分割数据集(LA, Pancreas, ACDC和PROMISE12)分享

这篇文章提供了四个常用的半监督医学分割数据集,所有数据集都已经被处理成了.h5文件。下载之后就可以直接使用

qq_45691955的博客 4174

Python 学习所遇问题

1、今天第一天学习,遇到了第一个错误 错误代码: print ‘hello’ 错误提示:missing parentheses in call to print (parentheses 圆括号的意思 , 在print的调用方法上丢失了圆括号) 错误解答:python3 取消了这样的用法,改用print (‘hello’)这样的用法 ...

Light_Jewel的专栏 608

无感无刷电机控制进阶:反电动势过零检测的5种实现方案对比

本文深入探讨无感无刷电机控制中反电动势过零检测的5种实现方案,包括电阻分压虚拟中性点法、专用BEMF检测IC方案、基于ADC采样的数字锁相环、无传感器观测器技术及混合方案创新实践。通过对比分析各方案的优劣及适用场景,为电机控制工程师提供实用的技术选型指南,助力提升系统性能与成本效益。

weixin_28691741的博客 843

ST-Link V2的隐藏技能:多通道串口调试的终极指南

本文深入探讨了ST-Link V2的多通道串口调试功能,突破传统烧录工具的限制。通过详细的硬件配置、Arduino IDE设置和实战案例,展示了如何利用SWD接口实现多通道数据监控,提升STM32F103C8T6等开发板的调试效率。文章还提供了PCB布局优化和性能调优技巧,助力开发者充分发挥ST-Link V2的潜能。

weixin_29285605的博客 355

最全的正则(python)基础知识

正则表达式 简介 起源于1951年数学家斯蒂芬·科尔·克莱尼发明的一种称之为“正则集合”的数学符号。 定义 即文本的高级匹配模式,提供搜索,替换等功能。其本质是由一系列字符和特殊符号构成的字串,这个字串即正则表达式。 原理 通过普通字符和有特定含义的字符,来组成字符串,用以描述一定的字符串规则,比如:重复,位置等,来表达某类特定的字符串,进而匹配。 普通字符 匹配规则:每个普通字符匹配其对应的字符 e.g. In : re.findall('ab',"abcdefabcd") Out: ['ab

Bruce.D的博客 1146

告别手动配置!用Vector vLinkGen 2.1.0自动生成AUTOSAR链接脚本(附bss段配置详解)

本文详细介绍了如何使用Vector vLinkGen 2.1.0工具自动生成AUTOSAR链接脚本,告别繁琐的手动配置。通过解析vLinkGen的核心架构和bss段配置实践,帮助开发者提升嵌入式软件开发效率,支持多种主流编译器,实现精确的内存分配和初始化策略。

weixin_28716181的博客 376

C++11 | 正则表达式(1)

介绍C++11里的正则表达式的简单用法,使用regex、smatch、sregex_iterator完成简单的正则匹配

安晓辉生涯——聚焦程序员的职业规划与成长 7652

Unity 编辑器篇|(四)编辑器拓展GUI类 (全面总结 | 建议收藏)

GUI 类是 Unity GUI 的接口,并且具有手动定位功能。“即时模式”GUI 系统(也称为 IMGUI)是一个完全独立的功能系统,不同于 Unity 基于游戏对象的主 UI 系统。IMGUI 是一个代码驱动的 GUI 系统,主要用作程序员的工具。为了驱动该系统,需在实现脚本上调用 OnGUI 函数即时模式 GUI 系统常用于:创建游戏内调试显示和工具。为脚本组件创建自定义检视面板。创建新的编辑器窗口和工具以扩展 Unity 本身。

游戏开发小Y的博客 12万+

PCL 最小生成树用于法向量定向【2025最新版】

PCL 最小代价生成树用于点云法向量的定向。博客长期更新,本文最近更新时间为:2025年9月15日。

点云侠的博客 2067

regex

The regex match and search interface //main.cpp #include #include using namespace std; void out(bool b) { cout << (b ? "found" : "not found") << endl; } int main() { // find XML/HTML-tagged

十年磨一剑 884

Python爬虫实战:东方财富股吧与雪球舆情数据实时爬取与情绪指标挖掘

本文详细介绍如何使用Python爬虫技术实时爬取东方财富股吧和雪球平台的讨论数据,结合股价波动构建情绪分析指标。我们将使用最新的异步爬虫技术、自然语言处理方法和可视化工具,为量化交易提供数据支持。文章包含完整的代码实现和技术细节,适合有一定Python基础的读者学习。

2201_76125261的博客 1222

C++11的正则表达式基本用法

1. 介绍 正则表达式(Regular Expression,常简写为regex、regexp或RE)。正则表达式通常被用来检索、替换那些符合某个模式(规则)的文本。C++11开始支持正则表达式。 正则表达式非常强大,具体的实现算法有差异,所以会有多种实现方式。C++11支持6种正则表达式引擎。ECMAScript 是其中支持最多元素的引擎,也是regex默认支持的引擎。 ECMAScript ...

飞鹤的程序员人生 6664

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

【C++进阶之路】C++11——正则表达式

正则表达式,简而言之就是用来匹配指定模式字符串的工具,在计算机的世界中,它发挥着很大的作用,比如编译器的词法分析,注册时验证密码的复杂度,爬虫爬取固定格式的数据时等场景都要用到。那么本篇的目的就是能够让大家快速上手正则表达式,并学会相关的接口。望对各位读者有所帮助。

Shun_Hua的博客 1164

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

C++11——正则表达式

1. 描述 C++11支持了正则表达式,主要算法有: regex_match,正则表达式要匹配整个字符串 regex_search,正则表达式可以匹配字符串中的一部分或全部 regex_replace,用一个字符串替换源字符串中匹配正则表达式的那部分子串 2. 使用 Regex.h #pragma once // 正则表达式 class CRegex { public: ...

Map的博客 1711

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

正则表达式(c++11)

C++11 引入了标准库中的 std::regex 类,用于支持正则表达式(Regular Expressions)。std::regex 类是 C++11 中正则表达式的核心,它提供了通过正则表达式对文本进行搜索、匹配、替换等操作的方法。

qq_37894034的博客 1016

C++11正则表达式的使用

title: C++11正则表达式的使用 tags: 正则表达式,c++11 author: 默默 time: 2019-3-24 22:01:00 什么是正则表达式 正则表达式是一种文本模式。正则表达式是强大、便捷、高效的文本处理工具。正则表达式本身,加上如同一门袖珍编程语言的通用模式表示法(general pattern notation),赋予使用者描述和分析文本的能力。配合上特定工具提供...

quotWhiteink_quot的博客 422

《C++11》深入剖析正则表达式库:解锁文本处理的高效之道

C++11正则表达式库为C++开发者提供了一个强大、灵活且高效的文本处理工具。通过深入理解正则表达式的基本概念、优势、应用场景以及C++11库的使用方法,我们可以在实际编程中轻松应对各种复杂的文本匹配、提取和替换任务。无论是在数据验证、数据清洗、文本分析还是其他需要处理文本的领域,正则表达式都能发挥重要作用。然而,正则表达式并非万能的。在面对一些极端复杂的文本处理需求时,如深度语义分析、自然语言处理等,可能需要借助更专业的工具和算法。

码事漫谈 2528

C++11 正则表达式匹配

C++11 正则表达式匹配的用法

小立仔 2409

C++11 Regex 正则表达式

C++11 原生已经支持了正则表达式,下面是一些简单的函数小测试 regex_search #include <regex> #include <string> #include <iostream> using namespace std; voi...

chouhunpo4240的博客 190

C++培训 C++11正则表达式

  上周给大家总结的C++11的新特性还没有归纳完,今天总结出两篇知识点,这是其中之一,知识是很多的,小编只要总结出来就会分享给大家,这篇文章介绍的是:C++ 11 新特性之正则表达式   对regex的完整支...

congbei8442的博客 167

[C++]C++11- 正则表达式

假如我们想要匹配的字符串中,有多个子串都可以匹配正则表达式,并且我们想把这些子串全部找出来,例如一个字符串中包含多个邮箱地址,那么就需要用到。假如我们不仅仅想知道一个正则表达式是否匹配一个字符串,我们还想要提取出匹配的部分,例如我们需要从邮箱中提取用户名和网址,就需要用到。值得注意的是,如果我们把这里的参数设为 -1,则迭代字符串中所有不匹配正则表达式的部分,相当于用正则表达式切割字符串。迭代的是所有正则表达式匹配中的指定子表达式,或迭代未匹配的子字符串。其实就是迭代字符串中所有正则表达式匹配的。

FL1768317420的博客 408

C++11 正则表达式——实例1

该实例通过一个函数is_email_valid 来检查一个email地址是否是一个正确的格式。如果格式正确则返回true。 #include &lt;regex&gt; #include &lt

linjcai的博客 389

C++ 11 新特性之正则表达式

这是C++11新特性介绍的第九部分,涉及到正则表达式相关的新特性。 不想细看的读者可以直接拉到文章最后看这部分的总结。 题外话 对regex的完整支持,直到g++4.9才算完善。我使用的系统是Ubuntu14.04,默认g++版本号是4.8.x,所以有一些regex功能无法编译通过。可以通过以下方法安装g++4.9: sudo add-apt-repository ppa:ubuntu-...

443

c++11特性之正则表达式

C++11中也将正则表达式纳入了新标准的一部分,不仅如此,它还支持了6种不同的正则表达式的语法,分别是:ECMASCRIPT、basic、extended、awk、grep和egrep。其中ECMASCRIPT是默认的语法,具体使用哪种语法我们可以在构造正则表达式的时候指定。正则表达式库提供表示正则表达式,这是一种用于字符串内执行模式匹配小型的语言的类。主要的类: basic_regex reg

一蓑烟雨任平生 也无风雨也无晴 5157
上一篇: C++11 lambda表达式
下一篇: php杂项
erlang_hell
博客等级 码龄14年 57粉丝 89原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值