C++11加入了正则表达式的支持,主要的类有:
- basic_regex,模板类,代表一个正则表达式对象,有两个方便的实例化类,regex和wregex,分别代表窄字符串和宽字符串表示的正则表达式
- sub_match,模板类,代表被子表达式匹配到的字符串,有csub_match、wcsub_match、ssub_match、wssub_match等四个实例化类方便使用
- match_results,模板类,代表了一个正则表达式匹配的结果,其中包含所有子表达式的匹配结果,有cmatch、wcmatch、smatch、wsmatch四个常见的实例化类
主要的算法有:
- regex_match,正则表达式要匹配整个字符串
- regex_search,正则表达式可以匹配字符串中的一部分或全部
- regex_replace,用一个字符串替换源字符串中匹配正则表达式的那部分子串
关于regex_match和regex_search有一个微妙的区别,下面的代码可以展示这一点:
const char text[] = u8"abc";
std::string strEx = "/home/foruok/20160406_153259.log";
std::regex re1("/home/.*/[0-9]{8}_[0-9]{6}\.log");
bool bMatch = std::regex_match(strEx, re1); // true
std::cout << "regex_match - " << bMatch << '\n';
bMatch = std::regex_search(strEx, re1); // true
std::cout << "regex_search - " << bMatch << '\n';
std::cout << "sub match test:\n";
std::regex re2("[0-9]{8}_[0-9]{6}");
bMatch = std::regex_match(strEx, re2); // false
std::cout << "regex_match - " << bMatch << '\n';
bMatch = std::regex_search(strEx, re2); // true
std::cout << "regex_search - " << bMatch << '\n';
主要的迭代器有:
- regex_iterator,模板类,可以枚举所有匹配结果,有cregex_iterator、wcregex_iterator、sregex_iterator、wsregex_iterator等实例化类。
- regex_token_iterator,模板类,有cregex_token_iterator、wcregex_token_iterator、sregex_token_iterator、wsregex_token_iterator等实例化类。
regex_iterator和regex_token_iterator这两者的区别是,后者可以枚举未匹配的token。
当你构造迭代器时,regex_iterator内部会调用regex_search来做正则匹配并记录结果;当你递增迭代器时,regex_iterator会维护内部的submatch集合。
迭代器解复用后就是match。比如sregex_iterator it...;
这样的代码,*it
的类型就是smatch。
还有一些其他的方法、类,先不提了,怪复杂的。这些类库使用起来,也可能有一些让人迷惑的地方。我们先看最简单的应用。
我们使用regex、sregex_iterator、smatch来做正则匹配。
假设有一个字符串,类似“231;876;0;911”,我们想把用“;”分隔的整数都提取出来,就可以用正则表达式。
函数如下:
void ExtractNumbers(std::string &str, vector < uint32_t> & numbers)
{
std::regex numRegex("(\\d+)");
auto numBegin = std::sregex_iterator(str.begin(),
str.end(),
numRegex);
auto numEnd = std::sregex_iterator();
for(std::sregex_iterator it = numBegin;
it != numEnd; ++it)
{
std::smatch match = *it;
std::string matchStr = match.str();
numbers.push_back(std::stoul(matchStr));
}
}
测试代码可能是这样的:
std::string strNumbers = "0;1;234";
std::vector<uint32_t> numbers;
std::cout << "\nnumbers:\n ";
ExtractNumbers(strNumbers, numbers);
for(auto i : numbers) std::cout << i << " ";
std::cout << std::endl;
使用迭代器是最简单的方法。我们也可以直接使用regex_search、regex_match,后面再举例子。
关于正则表达式本身,可以参考:正则表达式30分钟入门。
参考: