文档章节

Regex C++ : 正则表达式(2).

SHIHUAMarryMe
 SHIHUAMarryMe
发布于 2016/08/04 23:05
字数 2410
阅读 100
收藏 0

既然有了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个子串.

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

$' 匹配到的字符串的后缀.

$$ 字符$.

© 著作权归作者所有

共有 人打赏支持
SHIHUAMarryMe
粉丝 13
博文 164
码字总数 138212
作品 0
武汉
程序员
私信 提问
VS2008中使用正则表达式库Boost.Regex

VS2008中使用正则表达式库Boost.Regex 2011-04-14 10:10

香芋
2012/06/08
0
0
C++0x 已然拖成 C++1x

一个热爱 C++ 的程序员应该知道 C++0x 为何物吧。C++ 标准制定委员会曾在 1998 年和 2003 年制定和更新了 C++ 的标准,使 C++ 的编写更规范,功能也得到了提升。但是每次标准的制定后,委员会...

小编辑
2010/05/12
1K
11
C++新标准——C++1x

本文转自:http://liuyue.asia/2010/03/18/cpp0x-has-become-cpp1x/ 一个热爱 C++ 的程序员应该知道 C++0x 为何物吧。C++ 标准制定委员会曾在 1998 年和 2003 年制定和更新了 C++ 的标准,使...

张明
2010/03/18
4.1K
0
介绍 ATL CAtlRegExp,GRETA,Boost::regex 等正则表达式库

本文摘要翻译了几篇文章的内容,简单介绍 ATL CAtlRegExp,GRETA,Boost::regex 等正则表达式库,这些表达式库使我们可以方便地利用正则库的巨大威力,给我们的工作提供了便利。   正则表达...

香芋
2012/06/08
0
0
Posix正则表达式API说明

1 头文件 #include 2 基本方法 2.1 regcomp 函数原型 int regcomp(regex_t *preg, const char *regex, int cflags); 功能 编译正则表达式,以便regexec方法使用 参数含义 返回值 2.2 regexe...

lujun9972
2018/06/27
0
0

没有更多内容

加载失败,请刷新页面

加载更多

词法分析器flex教程

词法分析器flex教程 flex是基于正则表达式,用于对字符串进行提取和分析的工具。一般情况下,flex常用语编译器前端的词法分析阶段。flex程序读取用户输入的词法单元描述文件,生成lex.yy.c文...

陶小陶
12分钟前
1
0
IntelliJ IDEA 社区版没有 Spring Initializr

RT 解决办法 打开文件 - 设置 - 插件 输入 Spring 找到插件 Spring Assistant 并安装 下载可能会需要一点点时间 . 重启 IDEA 后,新建项目就可以看见 Spring Assistant 选项了...

taadis
15分钟前
0
0
MySQL执行计划 type类型

MySql提供了EXPLAIN语法用来进行查询分析,在SQL语句前加一个"EXPLAIN"即可。 explain select * from t_settlement_settle_order_detail where id = 2; 下面来介绍各个字段: type:连接类型......

ChyiHuang
18分钟前
1
0
mysql遇到的坑

sql_mode=NO_ENGINE_SUBSTITUTION 今天在测试库上发现使用GROUP BY 报错,我使用的mysql5.7 ONLY_FULL_GROUP_BY 对于GROUP BY聚合操作,如果在SELECT中的列、HAVING或者ORDER BY子句的列,没...

事儿爹
30分钟前
1
0
聊聊flink的InternalTimeServiceManager

序 本文主要研究一下flink的InternalTimeServiceManager InternalTimeServiceManager flink-streaming-java_2.11-1.7.0-sources.jar!/org/apache/flink/streaming/api/operators/InternalTim......

go4it
42分钟前
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部