文档章节

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

SHIHUAMarryMe
 SHIHUAMarryMe
发布于 2016/08/04 23:05
字数 2410
阅读 77
收藏 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
博文 162
码字总数 136638
作品 0
武汉
程序员
VS2008中使用正则表达式库Boost.Regex

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

香芋
2012/06/08
0
0
开源图形库 c语言-开源C++库

开源C++库必须具有以下特点:必须是成熟的产品、跨平台的产品、相对通用的库。   一、通用标准类   STL:C++标准模板库,呵呵,它也是开源的嘛。   boost:C++准标准库,它是强大地,江...

mickelfeng
2013/01/03
0
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
06/27
0
0
C++ 0x regex实现关键OR敏感字过滤

给出一篇文档,要求把里面的“性爱”都替换成“革命”,“性”都替换成“道德”。删除里面所有的“A片”。在所有的“苍井空来了”前面加上“(表相信)”,后面加上“(这是谣言)”。 要求:...

杨洋magic
2013/01/04
0
0

没有更多内容

加载失败,请刷新页面

加载更多

oracle 安装 PL/SQL Developer连接64位Oracle免安装配置

PL/SQL Developer连接64位Oracle 在64位系统上安装64位的Oracle数据库,但是没有对应的64位PL/SQL Developer,此时就不能使用PL/SQL Developer来进行直接连接的,所以要想实现连接还得需要其...

PeakFang-BOK
26分钟前
3
0
裁员寒冬袭来,30岁还在CRUD的Java程序员,拿什么安身立命?

就在近日,智联招聘公布的数据更是侧面印证了很多公司“瘦身”的事实:“2018年第二季度,小微企业用人需求较第一季度平均下降26.6%”。 裁员大潮正滚滚向前,席卷各行各业! 你做好失业的准...

Java填坑之路
28分钟前
4
0
第一章:什么是SpringCloud

第一章:什么是SpringCloud 何为微服务 在了解 SpringCloud之前,我们先来大致了解下 微服务这个概念吧。 传统单体架构 单体架构在小微企业比较常见,典型代表就是一个应用、一个数据库、一个...

DemonsI
34分钟前
8
0
环境搭建之八-- node.js和npm

1.node.js官网下载64位二进制压缩包 node-v8.12.0-linux-x64.tar.xz 2.解压文件 2.1 xz格式文件为 tar格式 xz -d node-v8.12.0-linux-x64.tar.xz 此时文件已经转变为 node-v8.12.0-linux-x64...

imbiao
38分钟前
4
0
JVM调优浅谈

1.数据类型 java虚拟机中,数据类型可以分为两类:基本类型和引用类型。 基本类型的变量保存原始值,即:它代表的值就是数值本身,而引用类型的变量保存引用值。 “引用值”代表了某个对象的...

xtof
42分钟前
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部