文档章节

Regex: 正则表达式(4)

SHIHUAMarryMe
 SHIHUAMarryMe
发布于 2016/08/07 20:48
字数 1160
阅读 37
收藏 0
点赞 0
评论 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
粉丝 12
博文 165
码字总数 138772
作品 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
317
0
C++ boost 正则表达式用法

什么是正则表达式?正则表达式是一种用来描述一定数量文本的模式。Regex代表Regular Express。 如果您不知道什么是正则表达式,请看这篇文章http://blog.csdn.net/begtostudy/archive/2007/...

zungyiu
2010/12/25
0
0
Java正则表达式通过回溯与前后查找提取标签中的内容

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

trayvon
2016/10/20
36
0
正则表达式测试工具 Regex Tester 的使用方法

正则表达式测试工具“RegexTester”,下载地址:http://www.oschina.net/p/regex+tester 一、关于本文 今天的工作中遇到了一些正则表达式,我需要检验它们是否正确,不过我对自己目测的结果又...

北风其凉
2015/07/28
0
0
正则表达式 (C++) (施工中)

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

shangluyi
2016/12/24
0
0
linux C 中使用正则表达式(转)

#include <stdio.h> #include <sys/types.h> #include <regex.h> / 取子串的函数 / static char substr(const charstr, unsigned start, unsigned end) { unsigned n = end - start; static......

元禛慎独
2016/09/26
10
0
10 个在线正则表达式测试网站

正则表达式,提供了简洁、灵活的手段,用于匹配文本字符串,如特定的字符,文字或字符样式。它对于初学者理解和使用所有的正则表达式语法是个头疼的事情。幸运的是,你可以获得在线帮助。 在...

老枪
2011/03/28
30.4K
10
C# WinForm开发系列 - Regular Expression

正则表达式用于字符串处理、表单验证等场合,实用高效。现将一些常用的表达式文章收集于此,以备不时之需。正则表达式能让更多的复杂的搜索和替换功能变成简单的操作。基本说来,正则表达式是...

长征2号
2017/11/07
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

gcviewer的使用

1、没有安装git软件 在编译打包GCViewer的过程中,不能执行git命令,错误信息如下: [ERROR] Failed to execute goal org.codehaus.mojo:buildnumber-maven-plugin:1.4:create (create-build...

刀锋
17分钟前
1
0
Android LogUtil 日志优化 调试的时候打印 点击跳转

打印日志的时候,可以点击跳转 LogUtil.java public class LogUtil { private static boolean IS_DEBUG = BuildConfig.DEBUG; public static void i(String tag, String message) {......

Jay_kyzg
27分钟前
0
0
人工智能你必须掌握的32个算法(二)归并排序算法

归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子...

木头释然
29分钟前
0
0
第十四章NFS服务搭建与配置

14.1 NFS介绍 NFS介绍 NFS是Network File System的缩写;这个文件系统是基于网路层面,通过网络层面实现数据同步 NFS最早由Sun公司开发,分2,3,4三个版本,2和3由Sun起草开发,4.0开始Netap...

Linux学习笔记
52分钟前
1
0
流利阅读笔记27-20180716待学习

生了娃照样能打,两位母亲温网会师 Lala 2018-07-16 1.今日导读 现今在生儿育女后回归事业的母亲们已经非常多见,但是很少有人想到,以高强度运动与竞争激烈为特色的竞技体育项目也会有 work...

aibinxiao
53分钟前
6
0
Guava 源码分析(Cache 原理【二阶段】)

前言 在上文「Guava 源码分析(Cache 原理)」中分析了 Guava Cache 的相关原理。 文末提到了回收机制、移除时间通知等内容,许多朋友也挺感兴趣,这次就这两个内容再来分析分析。 在开始之前...

crossoverJie
今天
0
0
OSChina 周一乱弹 —— 如果是你喜欢的女同学找你借钱

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @guanglun :分享Michael Learns To Rock的单曲《Fairy Tale》 《Fairy Tale》- Michael Learns To Rock 手机党少年们想听歌,请使劲儿戳(这...

小小编辑
今天
842
20
NNS域名系统之域名竞拍

0x00 前言 其实在官方文档中已经对域名竞拍的过程有详细的描述,感兴趣的可以移步http://doc.neons.name/zh_CN/latest/nns_protocol.html#id30 此处查阅。 我这里主要对轻钱包开发中会用到的...

暖冰
今天
0
0
32.filter表案例 nat表应用 (iptables)

10.15 iptables filter表案例 10.16/10.17/10.18 iptables nat表应用 10.15 iptables filter表案例: ~1. 写一个具体的iptables小案例,需求是把80端口、22端口、21 端口放行。但是,22端口我...

王鑫linux
今天
0
0
shell中的函数&shell中的数组&告警系统需求分析

20.16/20.17 shell中的函数 20.18 shell中的数组 20.19 告警系统需求分析

影夜Linux
今天
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部