既然有了std::basic_regex存储我们的正则表达式了,那我们怎么匹配到的字符串呢?
重点强调: 无论是std::regex_match还是std::regex_search都不能接受一个右值版本的std::basic_string!!!!!
下面我们将介绍:
std::regex_search:检验是否部分字符串匹配给定的正则表达式.
std::regex_match :检验是否整个字符串匹配给定的正则表达式.
- std::regex_search
//first: 一个指向被匹配字符串开始位置的迭代器.
//last: -个指向被匹配字符串结束位置的迭代器.
//m: 存放匹配的结果.
//e: 存放正则表达式.
//flags: 指出使用哪种正则表达式的语法.
template< class BidirIt,
class Alloc, class CharT, class Traits >
bool regex_search( BidirIt first, BidirIt last,
std::match_results<BidirIt,Alloc>& m,
const std::basic_regex<CharT,Traits>& e,
std::regex_constants::match_flag_type flags =
std::regex_constants::match_default );
//str: 被匹配的C风格的字符串.
//m: 存放匹配结果.
//e: 存放正则表达式.
//flags: 指出使用哪种正则表达式.
template< class CharT, class Alloc, class Traits >
bool regex_search( const CharT* str,
std::match_results<const CharT*,Alloc>& m,
const std::basic_regex<CharT,Traits>& e,
std::regex_constants::match_flag_type flags =
std::regex_constants::match_default );
//s: 存放一个被匹配的字符串.
//m: 存放匹配到的结果.
//e: 存放正则表达式.
//flags: 指出使用哪种正则表达式.
template< class STraits, class SAlloc,
class Alloc, class CharT, class Traits >
bool regex_search( const std::basic_string<CharT,STraits,SAlloc>& s,
std::match_results<
typename std::basic_string<CharT,STraits,SAlloc>::const_iterator,
Alloc
>& m,
const std::basic_regex<CharT, Traits>& e,
std::regex_constants::match_flag_type flags =
std::regex_constants::match_default );
//first: 一个指向被匹配字符串开始位置的迭代器.
//last: -个指向被匹配字符串结束位置的迭代器.
//e: 存放正则表达式.
//flags: 指出使用哪种正则表达式.
template< class BidirIt,
class CharT, class Traits >
bool regex_search( BidirIt first, BidirIt last,
const std::basic_regex<CharT,Traits>& e,
std::regex_constants::match_flag_type flags =
std::regex_constants::match_default );
//str: 被匹配的C风格的字符串.
//e: 存放正则表达式.
//flags: 指出使用哪种正则表达式.
template< class CharT, class Traits >
bool regex_search( const CharT* str,
const std::basic_regex<CharT,Traits>& e,
std::regex_constants::match_flag_type flags =
std::regex_constants::match_default );
//s: 存放一个被匹配的字符串.
//e: 存放正则表达式.
//flags: 指出使用哪种正则表达式.
template< class STraits, class SAlloc,
class CharT, class Traits >
bool regex_search( const std::basic_string<CharT,STraits,SAlloc>& s,
const std::basic_regex<CharT,Traits>& e,
std::regex_constants::match_flag_type flags =
std::regex_constants::match_default );
//不能接受一个右值的 std::basic_string<CharT>
template< class STraits, class SAlloc,
class Alloc, class CharT, class Traits >
bool regex_search( const std::basic_string<CharT,STraits,SAlloc>&&,
std::match_results<
typename std::basic_string<CharT,STraits,SAlloc>::const_iterator,
Alloc
>&,
const std::basic_regex<CharT, Traits>&,
std::regex_constants::match_flag_type flags =
std::regex_constants::match_default ) = delete;
Demo for std::regex_search:
#include <iostream>
#include <regex>
#include <string>
#include <utility>
int main()
{
std::basic_regex<char> re("<(.*)>(.*)</(\\1)>");
std::regex reg("<(.*)>(.*)</(\\1)>");
/*std::basic_string<char>*/ std::string data = "<person>\n"
"<first>Nico</first>\n"
"<last>Josuttis</last>\n"
"<person\n";
std::match_results<std::basic_string<char>::const_iterator> result;
std::basic_string<char>::const_iterator beg = data.cbegin();
std::basic_string<char>::const_iterator end = data.cend();
std::smatch result_;
for (; std::regex_search(beg, end, result_, re); beg = result_.suffix().first) {
std::cout << "------------------" << std::endl;
std::cout << "length: " << result_.length() << std::endl;
std::cout << result_.str() << std::endl;
}
return 0;
}
- std::regex_match
//检验这两个iterator范围内的字符串是否符合正则表达式
//另外我们可以给std::match_result提供allocator!
template< class BidirIt,class Alloc, class CharT, class Traits >
bool regex_match( BidirIt first, BidirIt last,
std::match_results<BidirIt,Alloc>& m,
const std::basic_regex<CharT,Traits>& e,
std::regex_constants::match_flag_type flags = std::regex_constants::match_default );
//检验这两个iterator范围内的字符串是否符合正则表达式.
//注意: 不用提供 std::match_result!
//不可以提供allocator.
template< class BidirIt, class CharT, class Traits >
bool regex_match( BidirIt first, BidirIt last,
const std::basic_regex<CharT,Traits>& e,
std::regex_constants::match_flag_type flags = std::regex_constants::match_default );
//接受一个C风格的字符串.
//并可以为std::match_result提供allocator!
template< class CharT, class Alloc, class Traits >
bool regex_match( const CharT* str,
std::match_results<const CharT*,Alloc>& m,
const std::basic_regex<CharT,Traits>& e,
std::regex_constants::match_flag_type flags = std::regex_constants::match_default );
//接受一个std::basic_string(可提供allocator)
//另外也可以为std::mathch_result提供allocator!
template< class STraits, class SAlloc, class Alloc, class CharT, class Traits >
bool regex_match( const std::basic_string<CharT,STraits,SAlloc>& s,
std::match_results<typename std::basic_string<CharT,STraits,SAlloc>::const_iterator, Alloc>& m,
const std::basic_regex<CharT,Traits>& e,
std::regex_constants::match_flag_type flags = std::regex_constants::match_default );
//接受一个C风格的字符串可不提供任何allocator!
//注意: 可以不提供std::match_results.
template< class CharT, class Traits >
bool regex_match( const CharT* str,
const std::basic_regex<CharT,Traits>& e,
std::regex_constants::match_flag_type flags =
std::regex_constants::match_default );
//接受一个std::basic_string(可以提供allocator).
//注意: 不用提供std::match_results.
template< class STraits, class SAlloc, class CharT, class Traits >
bool regex_match( const std::basic_string<CharT, STraits, SAlloc>& s,
const std::basic_regex<CharT,Traits>& e,
std::regex_constants::match_flag_type flags = std::regex_constants::match_default );
//我们不能指定一个右值版本的std::basic_string作为被匹配的对象
//该版本是被delete了的.
template< class STraits, class SAlloc, class Alloc, class CharT, class Traits >
bool regex_match( const std::basic_string<CharT,STraits,SAlloc>&&,
std::match_results<typename std::basic_string<CharT,STraits,SAlloc>::const_iterator, Alloc>&,
const std::basic_regex<CharT,Traits>&,
std::regex_constants::match_flag_type flags =
std::regex_constants::match_default ) = delete;
应该也注意到了上面所有版本的函数最后都指定了一个flag.
该flag是定义在std::regex_constants这个namespace中的一个enum.
std::regex_constants::match_default : 使用默认的方式匹配.
std::regex_constants::match_not_bol : 第一个字符不匹配(不匹配'^').
std::regex_constants::match_not_eol : 最后一个字符不匹配(不匹配'$').
std::regex_constants::match_not_bow : 第一个字符不匹配(转义序列'\b'被当作首字符不匹配).
std::regex_constants::match_not_eow : 最后一个字符不匹配(转义序列'\b'被当作尾字符不匹配).
std::regex_constants::match_any : 如果存在多余一个匹配,则可返回任意一个匹配.
std::regex_constants::match_not_null : 不匹配任何空序列.
std::regex_constants::continuous : 只试图匹配从第一个字符开始的子序列.
std::regex_constants::match_prev_avail : 第一个字符的前一个有效位置(造成忽略match_not_bol和match_not_bow).
- replace flag:
std::regex_constants::format_default : 用ECMAScript规则替换字符串.
std::regex_constants::format_se : 用POSIX set 规则替换字符串.
std::regex_constants::format_no_copy : 对未匹配的字符(或字符串)不予复制.
std::regex_constants::format_first_only : 只替换给定string中第一次匹配的地方.
正则表达式不仅用在我们希望查找一个给定序列的时候,还可以用在我们想要将找到的序列替换为另一个序列的时候.
重点注意: 替换操作都是在原字符串的拷贝上进行的,且std::regex_replace不用指定std::match_results;
- std::regex_replace
//OutputIt: 可以是std::ostream_iterator, 也可以是std::ostreambuf_iterator.
//BidIt first, last: 一对std::basic_string的迭代器,用于被正则表达式匹配.
//std::basic_regex我们指定的正则表达式.
//fmt: 我们指定的替换格式(它有一套替换规则稍后介绍)
//flag: 替换规则前面已经介绍了.
//返回: OutputIt类型.
template< class OutputIt, class BidirIt, class Traits, class CharT, class STraits, class SAlloc >
OutputIt regex_replace( OutputIt out, BidirIt first, BidirIt last,
const std::basic_regex<CharT,Traits>& re,
const std::basic_string<CharT,STraits,SAlloc>& fmt,
std::regex_constants::match_flag_type flags = std::regex_constants::match_default );
//OutputIt: 同上.
//BiddirIt: 同上.
//std::basic_regex: 同上.
//fmt: 通过C风格的字符串指定替换格式.
//flag: 同上.
//返回: OutputIt类型.
template< class OutputIt, class BidirIt, class Traits, class CharT >
OutputIt regex_replace( OutputIt out, BidirIt first, BidirIt last,
const std::basic_regex<CharT,Traits>& re,
const CharT* fmt,
std::regex_constants::match_flag_type flags = std::regex_constants::match_default );
//std::basic_string:指定被匹配的字符串.(可指定allocator)
//std::basic_regex: 指定正则表达式.
//fmt(std::basic_string):指定替换格式.(可指定allocator).
//flag: 指定替换规则.
//返回: std::basic_string类型.
template< class Traits, class CharT, class STraits, class SAlloc, class FTraits, class FAlloc >
std::basic_string<CharT,STraits,SAlloc>
regex_replace( const std::basic_string<CharT,STraits,SAlloc>& s,
const std::basic_regex<CharT,Traits>& re,
const std::basic_string<CharT,FTraits,FAlloc>& fmt,
std::regex_constants::match_flag_type flags = std::regex_constants::match_default );
//std::basic_string: 指定被匹配的字符串(可指定allocator).
//std::basic_regex: 指定正则表达式.
//fmt: 通过C风格的字符串指定替换格式.
//flag: 同上.
//return: 返回一个std::basic_string.
template< class Traits, class CharT, class STraits, class SAlloc >
std::basic_string<CharT,STraits,SAlloc> regex_replace( const std::basic_string<CharT,STraits,SAlloc>& s,
const std::basic_regex<CharT,Traits>& re,
const CharT* fmt,
std::regex_constants::match_flag_type flags = std::regex_constants::match_default );
//s: 通过C风格的字符串指定被匹配的字符串.
//re: 指定正则表达式.
//fmt: 指定替换格式.(可指定allocator).
//flag: 同上.
template< class Traits, class CharT, class STraits, class SAlloc >
std::basic_string<CharT> regex_replace( const CharT* s,
const std::basic_regex<CharT,Traits>& re,
const std::basic_string<CharT,STraits,SAlloc>& fmt,
std::regex_constants::match_flag_type flags = std::regex_constants::match_default );
//s:通过C风格的字符串指定被匹配的字符串.
//re: 指定正则表达式.
//fmt: 通过C风格的字符串指定替换格式.
//flag: 同上.
template< class Traits, class CharT >
std::basic_string<CharT> regex_replace( const CharT* s,
const std::basic_regex<CharT,Traits>& re,
const CharT* fmt,
std::regex_constants::match_flag_type flags =
std::regex_constants::match_default );
Demo for std::regex_replace:
#include <iostream>
#include <regex>
#include <string>
#include <utility>
#include <iterator>
int main()
{
std::basic_string<char> data = "<person>\n"
"<first>Nico</first>\n"
"<last>Josuttis</last>\n"
"</person>\n";
std::basic_regex<char> regex("<(.*)>(.*)</(\\1)>");
std::ostream_iterator<char> outPut(std::cout);
std::basic_string<char>::const_iterator pos{ data.cbegin() };
std::basic_string<char>::const_iterator end{ data.cend() };
std::basic_string<char> format{ "<$1 value=\"$2\"/>" };
std::cout << "----------------------" << std::endl;
std::regex_replace(outPut, pos, end, regex, std::string("<$1 value=\"$2\"/>"));
std::cout << "--------" << format << std::endl;
std::cout << "----------------------" << std::endl;
pos = data.cbegin();
end = data.cend();
std::basic_string<char> container;
std::regex_replace(std::back_inserter(container), pos, end, regex, std::string("<$$ value=\"$2\"/>"));
std::cout << container << std::endl;
std::cout << "-----------------------" << std::endl;
pos = data.cbegin();
end = data.cend();
std::basic_string<char> containerTwo;
//std::regex_replace(std::inserter(container, containerTwo.begin()), pos, end, regex, std::string("<$$ $‘ $' $$1 $$2>"));
std::regex_replace(std::back_inserter(containerTwo), pos, end, regex, std::string("<$&>"));
for (const auto& c : containerTwo) {
std::cout << c;
}
return 0;
}
接着我们来看一直 format的语法,在上面的例子中我们指定format的格式为: std::string("<$1 value=\"$2\"/>");
注意到我们使用了 $1 和 $2,其中$1代表正则表达式从data中匹配到的第一个符合正则表达式的第一个子串, $2代表从正则表达式中匹配到的第二个子串.
因此std::regex_replace(itr, pos, end, regex, format)的就是在format的副本的基础上进行替换. 比如:该表达式匹配到的第一个string为: <first>Nico</first> 其中的 first为第一个子串,Nico为第二个子串,</first>中的first为第三个子串. $1被替换为: first, $2被替换为:Nico.
我们来看一下 format的语法:
$& 匹配到的字符串.
$n 匹配到的字符串的第n个子串.
$' 匹配到的字符串的前缀.
$' 匹配到的字符串的后缀.
$$ 字符$.
来源:oschina
链接:https://my.oschina.net/u/2516597/blog/727546