C++简单的正则表达式知识点

定义于头文件 #include
template <class CharT, class Traits = std::regex_traits>
class basic_regex;

类型定义
regexbasic_regex
wregexbasic_regex<wchar_t>
成员类型定义
value_typeCharT
traits_typeTraits
string_typeTraits::string_type
locale_typeTraits::locale_type
flag_typestd::regex_constants::syntax_option_type
成员函数定义
mark_count返回正则表达式中有标记的子表达式数量
flags返回语法标志
常用常量定义
ECMAScript使用改 ECMAScript 正则表达式文法
basic使用基本 POSIX 正则表达式文法(文法文档)。
extended使用扩展 POSIX 正则表达式文法(文法文档)。
awk使用 POSIX 中 awk 工具所用的正则表达式文法(文法文档)。
grep使用 POSIX 中 grep 工具所用的正则表达式文法。这等效于 basic 选项附带作为另一种分隔符的换行符 ‘\n’ 。
egrep使用 POSIX 中 grep 工具带 -E 选项所用的正则表达式文法。这等效于 extended 附带 ’ | ’ 之外的作为另一种分隔符的换行符 ‘\n’ 。

因为 POSIX 使用“最左最长”匹配规则(最长的匹配子序列得到匹配,且若存在数个这种子序列,则匹配最左者),故它不适用的例子之一是剖析标签语言:如 “<tag[^>]>.” 这种 POSIX 正则表达式会匹配从首个 “<tag” 到最末 “” 的任何内容,包含中间的每个 “” 和 “” 。另一方面, ECMAScript 支持非贪心匹配,且 ECMAScript 正则表达式 “<tag[^>]>.?” 会只匹配到首个闭标签。

C++11 中,这些常量曾被指定带有冗余的关键词 static ,它为 C++14 通过 LWG 问题移除。

描绘匹配算法于 ECMAScript 与 POSIX 正则表达式之间的差异

#include <iostream>
#include <string>
#include <regex>
 
int main()
{
    std::string str = "zzxayyzz";
    std::regex re1(".*(a|xayy)"); // ECMA
    std::regex re2(".*(a|xayy)", std::regex::extended); // POSIX
 
    std::cout << "Searching for .*(a|xayy) in zzxayyzz:\n";
    std::smatch m;
    std::regex_search(str, m, re1);
    std::cout << " ECMA (depth first search) match: " << m[0] << '\n';
    std::regex_search(str, m, re2);
    std::cout << " POSIX (leftmost longest)  match: " << m[0] << '\n';
}

输出:

Searching for .*(a|xayy) in zzxayyzz:
 ECMA (depth first search) match: zzxa
 POSIX (leftmost longest)  match: zzxayy

常用ECMAScript 方式

正则表达式模式是一或多个以析取运算符 | 分隔的可选项可选项 (Alternative) 序列(换言之,析取运算符拥有最低优先级)

Pattern ::
Disjunction
Disjunction ::
AlternativeAlternative | Disjunction
模式首先尝试跳过析取 (Disjunction) 并匹配(析取后的)后随剩余正则表达式的可选项。

若它失败,则试图跳过左侧可选项并匹配右侧析取(后随剩余正则表达式)。

若左侧可选项、右侧析取和剩余正则表达式都拥有选择点,则在尝试移动到左侧可选项中的下个选择前,尝试剩余表达式值中的所有选择。若穷尽了左侧可选项中的所有选择,则取代左侧可选项尝试右侧析取。

跳过的可选项内的任何捕获括号产生空子匹配。

#include <iostream>
#include <regex>
 
// TODO :转换到接受宽字符序列
// std::match_results<std::basic_string<_ch>::const_iterator> m; 不行。
void show_matches(const std::string& in, const std::string& re)
{
    std::smatch m;
    std::regex_search(in, m, std::regex(re));
    if(m.empty()) {
        std::cout << "input=[" << in << "], regex=[" << re << "]: NO MATCH\n";
    } else {
        std::cout << "input=[" << in << "], regex=[" << re << "]: ";
        std::cout << "prefix=[" << m.prefix() << "] ";
        for(std::size_t n = 0; n < m.size(); ++n)
            std::cout << " m[" << n << "]=[" << m[n] << "] ";
        std::cout << "suffix=[" << m.suffix() << "]\n";
    }
}
 
int main()
{
    show_matches("abcdef", "abc|def");
    show_matches("abc", "ab|abc"); // 首先匹配左侧可选项
 
    // 针对后随剩余正则表达式 (c|bc) 左侧可选项 (a) 的匹配成功
    // 它生成 m[1]="a" 及 m[4]="bc" 。
    // 跳过的可选项 (ab) 和 (c) 将其子匹配 m[3] 和 m[5] 置为空。
    show_matches("abc", "((a)|(ab))((c)|(bc))");
}

输出:

input=[abcdef], regex=[abc|def]: prefix=[]  m[0]=[abc] suffix=[def]
input=[abc], regex=[ab|abc]: prefix=[]  m[0]=[ab] suffix=[c]
input=[abc], regex=[((a)|(ab))((c)|(bc))]: prefix=[]  m[0]=[abc]
m[1]=[a]  m[2]=[a]  m[3]=[] m[4]=[bc]  m[5]=[]  m[6]=[bc] suffix=[]

我的一个小例子

#include <iostream>
#include <regex>
#include <vector>
#include <string>
#include <set>
using namespace std;

int main()
{
    string str;
    regex e("cmd\\((.*)\\)");	// 要查找的字符串正则表达式, 需要注意的是使用\转义的时候,需要用\\转义成\ 然后再进行转义操作。
    smatch sm; // 将匹配的字符串进行保存, 有.str()方法转成C++字符串, 默认的也行
    set<string> s_str;                                                                                                                                                                                                                     
    while(getline(cin,str))
    {   
        regex_search(str, sm, e); 		// 匹配字符串,将结果保存至smatch 变量中
        // cout << sm[1]<<endl;
        s_str.insert(sm[1]);
    }   
    for(auto it : s_str)
    {   
        cout << it <<endl;
    }   
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值