定义于头文件 #include
template <class CharT, class Traits = std::regex_traits>
class basic_regex;
类型 | 定义 |
---|---|
regex | basic_regex |
wregex | basic_regex<wchar_t> |
成员类型 | 定义 |
---|---|
value_type | CharT |
traits_type | Traits |
string_type | Traits::string_type |
locale_type | Traits::locale_type |
flag_type | std::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;
}