Regex C++ : 正則表達式(2).

既然有了std::basic_regex存儲咱們的正則表達式了,那咱們怎麼匹配到的字符串呢?ios

重點強調: 不管是std::regex_match仍是std::regex_search都不能接受一個右值版本的std::basic_string!!!!!正則表達式

下面咱們將介紹:函數

std::regex_search:檢驗是否部分字符串匹配給定的正則表達式.spa

std::regex_match :檢驗是否整個字符串匹配給定的正則表達式.code

  • 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:orm

#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.ip

std::regex_constants::match_default : 使用默認的方式匹配.字符串

std::regex_constants::match_not_bol : 第一個字符不匹配(不匹配'^').string

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個子串.

$' 匹配到的字符串的前綴.

$' 匹配到的字符串的後綴.

$$ 字符$.

相關文章
相關標籤/搜索