文档章节

Regex: 正则表达式(4)

SHIHUAMarryMe
 SHIHUAMarryMe
发布于 2016/08/07 20:48
字数 1160
阅读 38
收藏 0

前面虽然介绍了一种方法能够逐一查找到给定string中可以匹配的内容,但是相对来说比较麻烦.

于是标准库提供了:

  • std::regex_iterator
template<class BidirIt,
         class CharT = typename std::iterator_traits<BidirIt>::value_type,
         class Traits = std::regex_traits<CharT>
        > class regex_iterator

std::regex_iterator::regex_iterator

regex_iterator();
	
regex_iterator(BidirIt a, BidirIt b, const regex_type& re,
               std::regex_constants::match_flag_type m =
                   std::regex_constants::match_default);

regex_iterator(const regex_iterator&);
	
regex_iterator(BidirIt, BidirIt, const regex_type&&,
               std::regex_constants::match_flag_type =
               std::regex_constants::match_default) = delete;

需要特别注意的是:

即使std::regex_iterator是一个class,我们并不能使用std::regex_iterator<BidirectionItr > iter;

而必须使用std::regex_iterator< BidirectionItr > iterator = std::regex_iterator<BidirectionItr >()

或者std::regex_iterator<itr> iterator = std::regex_iterator<itr>(BidirectionItr, BidirectionItr , std::basic_regex<type>);

看个例子就明白了:

#include <iostream>
#include <regex>
#include <string>
#include <iterator>

int main()
{
	std::basic_string<char> data("姓名: 唐彤 语文: 90 数学: 100 英语: 100");
	std::basic_regex<char> regex("[0-9]{1,}");
	std::basic_string<char>::const_iterator pos = data.cbegin();
	std::basic_string<char>::const_iterator end = data.cend();
	std::regex_iterator<std::basic_string<char>::const_iterator> regItr = 
		std::regex_iterator<std::basic_string<char>::const_iterator>(pos, end, regex);
	//std::regex_iterator<std::basic_string<char>::const_iterator> end;

	std::cout << std::distance(regItr, std::regex_iterator<std::basic_string<char>::const_iterator>()) << std::endl;

	for (; regItr != std::regex_iterator<std::basic_string<char>::const_iterator>(); ++regItr) {
		std::cout << std::boolalpha << std::is_same<decltype(*regItr), const std::match_results<std::basic_string<char>::const_iterator>&>::value << std::endl;
		std::cout << regItr->str() << std::endl;
	}

	return 0;
}

 

下面是标准库提供的切分器(tokenize):

1,所谓切分器就是说我们通过正则表达式匹配从给定string匹配我们不想要的内容,然后提取出来两个不想要的内容值之间的内容!

2,我们通过指定正则表达式匹配给定string中的内容但是,我们只对匹配到内容的某个子串感兴趣的时候也可以通过制定submatchs来只保存对我们有用的子串.

  • std::regex_token_iterator
template<class BidirIt,
         class CharT = typename std::iterator_traits<BidirIt>::value_type,
         class Traits = std::regex_traits<CharT>
         > class regex_token_iterator

我们必须提供一个双向的迭代器(BidirectionalIterator) 进去!

//默认构造函数一般被当作end来使用.
regex_token_iterator();

//传入2个双向只读迭代器(iterator),一个std::basic_regex,并且指定一个submatch(稍后详细介绍).
regex_token_iterator( BidirectionalIterator a, BidirectionalIterator b,
                      const regex_type& re,
                      int submatch = 0,
                      std::regex_constants::match_flag_type m =
                          std::regex_constants::match_default );

//传入2个双向只读迭代器(iterator),一个std::basic_regex,并且通过一个vector来指定我们感兴趣的子串.
regex_token_iterator( BidirectionalIterator a, BidirectionalIterator b,
                      const regex_type& re,
                      const std::vector<int>& submatches,
                      std::regex_constants::match_flag_type m =
                          std::regex_constants::match_default );

//传入2个双向只读迭代器,一个std::basic_regex,并且通过initializer_list来指定匹配到的我们感兴趣的子串.
regex_token_iterator( BidirectionalIterator a, BidirectionalIterator b,
                      const regex_type& re,
                      std::initializer_list<int> submatches,
                      std::regex_constants::match_flag_type m =
                          std::regex_constants::match_default );

//传入2个双向只读迭代器,一个std::basic_regex,并且通过一个数组来指定匹配到的我们感兴趣的子串.
template <std::size_t N>
regex_token_iterator( BidirectionalIterator a, BidirectionalIterator b,
                      const regex_type& re,
                      const int (&submatches)[N],
                      std::regex_constants::match_flag_type m =
                          std::regex_constants::match_default );

//拷贝构造函数.
regex_token_iterator( const regex_token_iterator& other );

//不能接受一个右值的std::basic_regex.
regex_token_iterator( BidirectionalIterator a, BidirectionalIterator b,
                      const regex_type&& re,
                      int submatch = 0,
                      std::regex_constants::match_flag_type m =
                          std::regex_constants::match_default ) = delete;
	
regex_token_iterator( BidirectionalIterator a, BidirectionalIterator b,
                      const regex_type&& re,
                      const std::vector<int>& submatches,
                      std::regex_constants::match_flag_type m =
                          std::regex_constants::match_default ) = delete;

regex_token_iterator( BidirectionalIterator a, BidirectionalIterator b,
                      const regex_type&& re,
                      std::initializer_list<int> submatches,
                      std::regex_constants::match_flag_type m =
                          std::regex_constants::match_default ) = delete;

template <std::size_t N>
regex_token_iterator( BidirectionalIterator a, BidirectionalIterator b,
                      const regex_type&& re,
                      const int (&submatches)[N],
                      std::regex_constants::match_flag_type m =
                          std::regex_constants::match_default ) = delete;

Demo for std::regex_token_iterator:

#include <iostream>
#include <utility>
#include <regex>
#include <string>
#include <vector>

int main()
{
	std::basic_string<char> data = "<person>\n"
		                           "<first>Nico</first>"
		                           "<last>Josuttis</last>"
		                           "</person>";
	std::basic_regex<char> regex("<(.*)>(.*)</\\1>");
	std::regex_token_iterator<std::basic_string<char>::const_iterator> beg(data.cbegin(), data.cend(), regex, { 0, 2 });
	std::regex_token_iterator<std::basic_string<char>::const_iterator> end;

	std::cout << std::boolalpha << std::is_same<decltype(*beg), const std::sub_match<std::basic_string<char>::const_iterator>&>::value << std::endl;

	for (; beg != end; ++beg) {
		std::cout << beg->length() << std::endl;
		std::cout << beg->str() << std::endl;
	}


	std::cout << "----------------------" << std::endl;
	std::basic_string<char> names("nico,jim,helmut,paul,tim,john,paul,rita");
	std::basic_regex<char> regex_("[,:.]+");
	//上面通过正则表达式指定为分割器.
	//上面的正则表达式指出: 从给定的string(names)中匹配 ,或:或.至少一次.
	//但是我们的本意是不想要这些 ,:.于是切分器就提供了这样的功能.


	std::basic_string<char>::const_iterator _beg = names.cbegin();
	std::basic_string<char>::const_iterator _end = names.cend();

	//注意下面的最后一个参数我们指定为: -1.
	std::regex_token_iterator<std::basic_string<char>::const_iterator> pos(_beg, _end, regex_, -1);
	std::regex_token_iterator<std::basic_string<char>::const_iterator> end_;
	for (; pos != end_; ++pos) {
		std::cout << pos->str() << std::endl;
	}

	return 0;
}

上面的std::regex_token_iterator除了可以指定std::regex_constants::match_flag_type之外还可以指定一个额外的参数:

1,可以是一个int.

2,可以是一个std::vector,

3,可以是一个std::initializer_list.

4,可以是一个数组.

比如上面的Demo中我们指出:

{0, 2} : 它的含义是我们只对每次匹配到的string中的第二个子串感兴趣.

-1:表明我们对正则表达式两次匹配之间的内容感兴趣.

n(>0) : 表明我们对第n次匹配到的string感兴趣.

 

© 著作权归作者所有

共有 人打赏支持
SHIHUAMarryMe
粉丝 13
博文 164
码字总数 138212
作品 0
武汉
程序员
私信 提问
Regex C++: 正则表达式(1)

自C++11起标准库提供了正则表达式库,允许我们使用通配符和pattern来查找和替换掉string中的字符. Match: 将整个string拿来匹配某个regex. Search: 查找某个string中与regex吻合的部分. Rep...

SHIHUAMarryMe
2016/08/03
67
0
VS2008中使用正则表达式库Boost.Regex

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

香芋
2012/06/08
0
0
正则表达式经典教程

作者:ET Dreams http://blog.csdn.net/etmonitor/ Regular Expressions (1) ---- What is Regular Expressions? 正则表达式是常见常忘,所以还是记下来比较保险,于是就有了这篇笔记。 希望...

晨曦之光
2012/03/09
330
0
Java正则表达式通过回溯与前后查找提取标签中的内容

在说具体的内容之前先来了解一下什么是向前查找,向后查找与回溯。我们通过一下小的例子来理解一下。具体的代码附录在最后。 向前查找 Java中向前查找的正则表达式是(?=),更加具体的就是 要...

trayvon
2016/10/20
36
0
正则表达式 (C++) (施工中)

先来看一个例子,要求写一段代码,实现如下功能: 从标准输入中读取一行字符串, 从中读取所有邮箱的格式; 对于这个问题,用传统的方式是可以解决的: 我们可以用解析字符串的方式实现,需要...

shangluyi
2016/12/24
0
0

没有更多内容

加载失败,请刷新页面

加载更多

exportfs命令, vsftp搭建ftp服务

exportfs命令 当修改/etc/exports文件后,更改的内容是不会立即生效的。如果重启nfs服务,会导致客户端重启期间的请求是挂起等待的,可以把客户端的挂载umount进行卸载后,再重启nfs服务,但...

野雪球
11分钟前
1
0
编程价值观、原则、模式

读自《实现模式》 模式,即是针对特定问题的通用解决方案。 每个模式都承载这一点点理论,但实际编程中存在着一些更加深远的影响力,远不是孤立的模式所能概括的。 价值观是编程过程的统一支...

遥借东风
24分钟前
1
0
php分割二级域名做跳转处理方法

使用php中的全局变量 $_SERVER['HTTP_HOST'] ,可以获得用户当前访问的域名字符串,在这里面查询自己定义的各个子域名字符串,然后使用header函数重定向到不同的页面 代码如下 if( strpos($...

Mr_Azaz
26分钟前
2
0
容器之Zookeeper的使用

我们使用zookeeper时,都是在Linux上安装zookeeper,之后启动时要加入配置文件。 使用docker之后,我们可以直接使用镜像运行容器,镜像可以从docker.hub上下载,地址是https://hub.docker.co...

克虏伯
昨天
3
0
esxi 更换ssl证书

概述 就是想换一个证书而已,你可以通过下面的途径去申请一个泛解析域名的证书之后再esxi上安装上 使用阿里云域名api申请Let’s Encrypt泛域名免费ssl证书 申请完成证书之后进行下一步 操作 ...

bboysoulcn
昨天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部