Day22:C++智能指针和正则表达式

目录

一、智能指针

1.智能指针的本质:

2.“何谓智能”:

3.三种常用的智能指针:

        ①shared_ptr

        ②weak_ptr

        ③unique_ptr

二、正则表达式的预备知识

        1.具有特殊意义的元字符

        2. 量词元字符

        3.校验数字的表达式 

        4.校验字符的表达式 

        5. 特殊需求表达式(copy时,去空格+改成双‘\’)

 三、正则表达式在C++中的应用

        1.匹配  bool regex_match(string str,regex reg);        

        ①匹配用户输入的邮箱

        ②匹配某一个字符串(会区分大小写!)

        ③ 通过设置参数,设置不区分大小写字母

        ④字符串也可以直接充当正则规则(必须一一对应!!!)

        2. 正则替换string regex_replace(string str,regex reg, string newstr);

        ①正常匹配 (两种写法)

        ②控制替换,仅替换第一次出现的  regex_constants::format_first_only

        ③不拷贝方式(不返回与匹配内容无关的字段,相关的字段全部进行替换)                           regex_constants::format_no_copy        

        3.截取处理字符串       

                ① 法一:bool regex_search(string str,smatch result,regex reg) 

                                             不改变原字符串

                ②法二:srgex_iterator

                ③法三:                                                                                                                           sregex_token_iterator(iterator begin,iteartor end,regex regex, int flag);


一、智能指针

头文件:(管理内存)

#include<memory>

1.智能指针的本质:

        是一个模板类,一般使用是用的这个类的对象,而不是指针

2.“何谓智能”:

        体现在内存释放问题。用智能指针管理new的对象, 将不在需要手动delete

3.三种常用的智能指针:

        ①shared_ptr

              A.申请内存初始化及访问数据(实例化用的int类型而非int*!!!!,其余数据类型同理)

    //1.基本用法
	//new int(1111)申请内存做初始化
	//1.1 做初始化
	shared_ptr<int> pInt(new int(1111));	
	//1.2 访问数据
	cout << *pInt << endl;  //*指针
	//shared_ptr<int> pNum = new int(222);  错误.


class  WBM 
{
public:
	void print() 
	{
		cout << "打印" << endl;
	}
	~WBM()
	{
		cout << "析构函数被调用" << endl;
	}
protected:
};
//2.自定义类型
	{
		shared_ptr<WBM> pMM(new WBM);
		//WBM* p = new WBM;	 //手动释放
		pMM->print();
		WBM* pM = pMM.get();
	}

输出: 

1111
打印
析构函数被调用

         构造出share_ptr对象的第二种写法->用make_shared()方法

	shared_ptr<int>  pMake = make_shared<int>(12);
	cout << *pMake << endl;
	//make_shared管理自定义类型,参数个数由构造函数决定

              B.常用成员函数:

                (i)get() 函数: 返回数据的指针的引用

    //get()函数
	shared_ptr<int> pInt(new int(1111));	
	int* pData = pInt.get();

        注: 当通过get()获得指针时,不能够手动释放pData——>会引起二次析构问题

                (ii)use_count(): 返回的是管理对象的智能指针对象数

                        (n个智能指针共同管理同一个数据,返回n)->“共用”

    //use_count()函数
	shared_ptr<int> aptr(new int(10));
	cout <<"get读取数据:" << *aptr.get() << endl;
	cout << "正常使用:" << *aptr<<endl;
	cout <<"管理对象的指针数:" << aptr.use_count() << endl;
	shared_ptr<int> bptr(aptr);
	cout << "管理对象的指针数:" << aptr.use_count() << endl;
	cout << "管理对象的指针数:" << bptr.use_count() << endl;
	shared_ptr<int> cptr;		
	if (!cptr) 
	{
		cout << "空智能指针对象" << endl;
	}
	cptr = bptr;
	cout << "管理对象的指针数:" << cptr.use_count() << endl;

输出: 

get读取数据:10
正常使用:10
管理对象的指针数:1
管理对象的指针数:2
管理对象的指针数:2
空智能指针对象
管理对象的指针数:3

                (iii)swap():交换管理对象

                (iv)reset():重置管理对象

    //swap();
	//reset(); 重新设置管理对象
    void printData(shared_ptr<WBM>& pMM)
    {
    	pMM->print();
    	cout << "管理对象的指针数:" << pMM.use_count() << endl;
    }

	shared_ptr<int> aa(new int(12));
	shared_ptr<int> bb(new int(21));
	aa.swap(bb);
	cout << "aa:" << *aa << "\tbb:" << *bb << endl;
	cout << "管理对象的指针数:" << aa.use_count() << endl;
	bb.reset(new int(123));
	cout << "bb:" << *bb << endl;
	{
		cout << "当做函数参数....." << endl;
		shared_ptr<WBM> pMM(new WBM);
		cout << "管理对象的指针数:" << pMM.use_count() << endl;
		printData(pMM);
	}

输出:

aa:21   bb:12
管理对象的指针数:1
bb:123
当做函数参数.....
管理对象的指针数:1
打印
管理对象的指针数:1
析构函数被调用

              C.带删除器的写法

                若是管理的一段内存,那就必须写带删除器的写法,

        (删除器:理解为自己写释放内存的过程->第二个参数为函数指针(可有三种方法))

    //4.带删除器的写法
	//删除器: 理解为自己写释放内存的过程
    void freeFile(FILE* fp) 
    {
	    free(fp);
	    cout << "文件释放成功" << endl;
    }
    {/*此处用的是lambda表达式作为第二个参数(删除器)!!!*/
		cout << "带删除器写法....." << endl;
		shared_ptr<WBM> p(new WBM[4], [](WBM* array) {delete[] array; });
	}
	shared_ptr<FILE> pf(fopen("1.txt", "w"), freeFile);/*采用的函数指针作为删除器*/

输出:

带删除器写法.....
析构函数被调用
析构函数被调用
析构函数被调用
析构函数被调用
文件释放成功

        ②weak_ptr

                A.弱引用指针,不会累计计数(应用场景比较单一)

                B.weak_ptr只能通过shared_ptr或者weak_ptr来构造(不能直接管理数据)

                C.主要应用场景: 为了解决shared_ptr 循环引用内存导致无法释放问题

                D.不可使用* 取值,能使用->取值

                E.通过成员函数lock获取shared_ptr对象 然后再访问数据

                   例1:常规使用(访问数据的方法)

class MM 
{
public:
	MM() {}
	void print() 
	{
		cout << "打印" << endl;
	}
	~MM() { cout << "析构" << endl; }
protected:
};    
    shared_ptr<MM> pMM(new MM);
	shared_ptr<MM> pMM2 = pMM;
	cout << "计数:" << pMM2.use_count() << endl;
	weak_ptr<MM> pwMM(pMM);
	cout << "计数:" << pMM2.use_count() << endl;
	//(*pwMM).print();//weak_ptr不存在这种访问方式
	//pwMM.lock(): shared_ptr对象
	pwMM.lock().get()->print();
	(pwMM.lock())->print();

  输出:

   计数:2
   计数:2
   打印
   打印

                        例2:应用场景(解决share_ptr的循环引用问题->内存泄露)

class B;
class A 
{
public:
	A() { cout << "A" ;}
	~A() { cout << "~A"; }
	weak_ptr<B> b;
};
class B 
{
public:
	B() { cout << "B"; }
	~B() { cout << "~B"; }
	weak_ptr<A> a;
};
void testLoopUse() 
{
	cout << "循环引用....." << endl;
	shared_ptr<A> aObject(new A);
	shared_ptr<B> bObject(new B);
	aObject->b = bObject;
	bObject->a = aObject;
	cout << endl << "计数:" << bObject.use_count() << endl;
	cout << endl;
}

输出: 

循环引用.....
AB
计数:1

~B~A
12
析构

        ③unique_ptr

                A.禁止拷贝和赋值,独占型(无use_count方法!)

                B.也可以用make_unique去构造出对象

    unique_ptr<MM> pMM(new MM(1111));
	unique_ptr<int> mynum = make_unique<int>(666);
	//unique_ptr<MM> pMM2(pMM);			// 错误
	unique_ptr<MM> pMM3;	
	//pMM3 = pMM2;						// 错误
	cout << "MM num:" << pMM->getNum() << endl;
	cout << "MM num:" << pMM.get()->getNum() << endl;

                C.任何时候unqiue_ptr操作管理对象,永远都只有一个有效

                        (i)可以通过move函数转交所有权 (原ptr就不能再去访问了!!)两种写法(move语句ormove构造)转接所有权后,可以用reset重新赋值

                        (ii)reset函数结合release函数移交所有权(不用release本质上也是一种赋值,所以会报错。)

class MM 
{
public:
	MM() {}
	MM(int num) :num(num) {}
	int getNum() { return num; }
	~MM() { cout << "MM:" << num << endl; };
protected:
	int num=0;
};
    //move转交所有权
	pMM3 = move(pMM);
	cout << "MM num:" << pMM3->getNum() << endl;
	//cout << "MM num:" << pMM->getNum() << endl; // pMM不在管理对象
	unique_ptr<MM> pMM4(move(pMM3));  //MM&& 

	//可以重新设置
	pMM.reset(new MM(1));
	cout << "MM num:" << pMM->getNum() << endl;
	unique_ptr<MM> pMM5;
	pMM5.reset(pMM4.release());
	cout << pMM5->getNum() << endl;

                D.访问数据:有get方法,也可以直接当做一个指针使用。

                E:构造unique_ptr对象时除了传递指针外,还可以提供一个删除器。如果没有指定删除器,unique_ptr会使用缺省删除器,即缺省使用delete和delete[]来销毁对象,分别用于普通版本和数组版本。如果动态分配的资源有专门的释放函数,必须在构造时同时提供一个删除器。比如:

unique_ptr<int, void(*)(int*)> up2(new int(4), 
    [](int *ptr){delete ptr;});
unique_ptr<int[], function<void(int*)>> ar_up2(new int[10],
     [](int *ptr){delete[] ptr;});

注: 删除器要求是可调用对象,它的类型可以是函数指针、函数对象、lambda表达式、function对象等。->下面是仿函数释放+lambda释放的方法

class MM 
{
public:
	MM() {}
	MM(int num) :num(num) {}
	int getNum() { return num; }
	~MM() { cout << "MM:" << num << endl; };
protected:
	int num=0;
};
struct DeleteMM 
{
	void operator()(MM* mm) 
	{
		delete[]  mm;
		cout << "释放成功...." << endl;
	}
};
	//删除器
	{
		unique_ptr<MM, DeleteMM> p(new MM[3]);
		unique_ptr<MM, void(*)(MM*)> pp(new MM[3],
			[](MM* mm) {delete[]mm; });
	}

当使用提供删除器时,删除器的类型也要作为模板的参数类型声明在unique_ptr中也就是说删除器类型也是unique_ptr模板实例化后的类型的一部分。因此,如果一个unique_ptr对象在move时,源和目的unique_ptr对象的删除器类型也必须一样,这点与shared_ptr不一样

一般情况下,unique_ptr释放的资源是在内存中动态分配的,但通过定制删除器,也可以使用unique_ptr来管理一些通过其他方式分配的资源,比如文件句柄、socket等。C++中有一种资源管理的惯例-RAII,可以通过它来实现对资源的自动释放,比如,对于使用fopen打开的文件,返回一个文件指针FILE,在程序结束时,需要调用fclose关闭,为了防止忘记关闭,可以手动编写一个RAII类来负责管理这个FILE的生命周期,不是很方便。现在可以使用unique_ptr来实现,只需定义一个删除器就可以了,非常方便。下面是一个使用unique_ptr来自动关闭打开文件的例子

FILE *file = fopen("/tmp/tmp.txt", "r"); // 分配FILE资源
unique_ptr<FILE, void(*)(FILE *)> up(file, [](FILE *file) {
	fclose(file);
});
...//其它操作file的代码逻辑

二、正则表达式的预备知识

        1.具有特殊意义的元字符

 \:\字符能够改变字符原本的含义

^:^字符指示字符串的头,且要求字符串以字符开头,不占位。\^表示一个真正的^符号。

$:$字符指示字符串的尾,且要求字符串以字符结尾,不占位。\\$表示一个真正的$符号。

():分组,大正则中包含小正则。可以改变默认的优先级。在模式中可以使用\1来表示第一组已然捕获到的东西,\2来表示第二组已然捕获到的东西。

\b:指示字符串的边界(头/尾/空格左/空格右),字符\b要求边界的左边是字符,\b字符要求边界的右边是字符。

.:表示一个除了\n以外的任意一个字符。\\.表示一个真正的.符号。

|:a|b  a或b之一

[abc]:abc之中的任意一个

\[^abc]:  abc之外的

\[a-z]:    任意小写字母

\[^a-z]:  除了小写字母之外的

\w:任意一个字母数字下划线,等价于[(0-9)(a-z)(A-Z)(_)]

\W:字母数字下划线之外的,等价于[]

\d:    任意一个数子

\D:    除了数字之外的

\s:    空白符(空格、制表符、换页符)

        2. 量词元字符

*:字符*要求字符出现0到多次 {0,}

+:字符+要求字符出现1到多次 (\w) {1,}

?:字符?要求字符出现0次或1次 {0,1}

{n}:字符{n}要求字符出现n次

{n,}:字符{n,}要求字符出现n到多次 {0,}

{n,m}:字符{n,m}要求字符出现n到m次、

所以含有\的元字符,在C++定义时,都要写成\\   

        3.校验数字的表达式 

数字:^ [0 - 9] * $

n位的数字:^ \d{ n }$

至少n位的数字:^ \d{ n, }$

m - n位的数字: ^ \d{ m,n }$

零和非零开头的数字: ^ (0 | [1 - 9][0 - 9] *)$

非零开头的最多带两位小数的数字: ^ (\[1 - 9][0 - 9] *) + (.[0 - 9]{ 1,2 }) ? $

带1 - 2位小数的正数或负数: ^ (\ - ) ? \d + (\.\d{ 1,2 }) ? $

正数、负数、和小数: ^ (\ - | \ + ) ? \d + (\.\d + ) ? $

有两位小数的正实数: ^ [0 - 9] + (.[0 - 9]{ 2 }) ? $

有1~3位小数的正实数: ^ [0 - 9] + (.[0 - 9]{ 1,3 }) ? $

非零的正整数: ^ [1 - 9]\d * $ 或 ^ ([1 - 9][0 - 9] *) { 1, 3 }$ 或^ \ + ? \[1 - 9][0 - 9] * $

非零的负整数: ^ \ - [1 - 9][]0 - 9"$ 或 ^-[1-9]\d$

非负整数: ^ \d + $ 或 ^ [1 - 9]\d * | 0$

非正整数: ^ -[1 - 9]\d * | 0$ 或 ^ ((-\d + ) | (0 + ))$

非负浮点数: ^ \d + (.\d + ) ? $ 或 ^ [1 - 9]\d * .\d * | 0.\d * [1 - 9]\d * | 0 ? .0 + | 0$

非正浮点数: ^ ((-\d + (.\d + ) ? ) | (0 + (.0 + ) ? ))$ 或 ^ (-([1 - 9]\d * .\d * | 0.\d * [1 - 9]\d*)) | 0 ? \.0 + | 0$

正浮点数: ^ [1 - 9]\d * .\d * | 0.\d * [1 - 9]\d * $ 或 ^ (([0 - 9] + .[0 - 9] * [1 - 9][0 - 9] *) | ([0 - 9] * [1 - 9][0 - 9] * .[0 - 9] + ) | ([0 - 9] * [1 - 9][0 - 9] *))$

负浮点数: ^ -([1 - 9]\d * .\d * | 0.\d * [1 - 9]\d*)$ 或 ^ (-(([0 - 9] + .[0 - 9] * [1 - 9][0 - 9] *) | ([0 - 9] * [1 - 9][0 - 9] * .[0 - 9]) | ([0 - 9] * [1 - 9][0 - 9] *)))$

浮点数: ^ (-? \d + )(.\d + ) ? $ 或 ^ -? ([1 - 9]\d * .\d * | 0.\d * [1 - 9]\d * | 0 ? .0 + | 0)$

        4.校验字符的表达式 

汉字: ^ [\u4e00 - \u9fa5]{ 0, }$
英文和数字: ^ [A - Za - z0 - 9] + $ 或 ^ [A - Za - z0 - 9]{ 4,40 }$
长度为3 - 20的所有字符: ^ .{3, 20}$
由26个英文字母组成的字符串: ^ [A - Za - z] + $
由26个大写英文字母组成的字符串: ^ [A - Z] + $
由26个小写英文字母组成的字符串: ^ [a - z] + $
由数字和26个英文字母组成的字符串: ^ [A - Za - z0 - 9] + $
由数字、26个英文字母或者下划线组成的字符串: ^ \w + $ 或 ^ \w{ 3,20 }$
中文、英文、数字包括下划线: ^ [\u4E00 - \u9FA5A - Za - z0 - 9_] + $
中文、英文、数字但不包括下划线等符号: ^ [\u4E00 - \u9FA5A - Za - z0 - 9] + $ 或 ^ [\u4E00 - \u9FA5A - Za - z0 - 9]{ 2,20 }$
可以输入含有 ^ %&',;=?$\"等字符:\[^%&', ; = ? $\x22] + 12

禁止输入含有~的字符:\[^ ~\x22] +

        5. 特殊需求表达式(copy时,去空格+改成双‘\’)

Email地址: ^ \w + ([-+.]\w + ) * @\w + ([-.]\w + ) * \.\w + ([-.]\w + ) * $
域名:\[a - zA - Z0 - 9][-a - zA - Z0 - 9]{ 0,62 }(/ .\[a - zA - Z0 - 9][-a - zA - Z0 - 9]{ 0,62 }) + / . ?
InternetURL:[a - zA - z] + ://[^\s]* 或 ^http://([\w-]+\.)+[\w-]+(/[\w-./?%&=]*)?$
手机号码: ^ (13[0 - 9] | 14[5 | 7] | 15[0 | 1 | 2 | 3 | 5 | 6 | 7 | 8 | 9] | 18[0 | 1 | 2 | 3 | 5 | 6 | 7 | 8 | 9])\d{ 8 }$
电话号码(0511 - 4405222、021 - 87888822):\d{ 3 } - \d{ 8 } | \d{ 4 } - \d{ 7 }
身份证号(15位、18位数字): ^ \d{ 15 } | \d{ 18 }$
短身份证号码(数字、字母x结尾): ^ ([0 - 9]) { 7, 18 }(x | X) ? $ 或 ^ \d{ 8,18 } | [0 - 9x]{ 8,18 } | [0 - 9X]{ 8,18 } ? $
帐号:(字母开头,允许5 - 16字节,允许字母数字下划线): ^ \[a - zA - Z][a - zA - Z0 - 9_]{ 4,15 }$
密码:(以字母开头,长度在6~18之间,只能包含字母、数字和下划线): ^ [a - zA - Z]\w{ 5,17 }$
强密码(必须包含大小写字母和数字的组合,不能使用特殊字符,长度在8 - 10之间):* ^ (? = .*\d)(? = .*[a - z])(? = .*[A - Z]).{8, 10}$
日期格式: ^ \d{ 4 } - \d{ 1,2 } - \d{ 1,2 }
一年的12个月(01~09和1~12): ^ (0 ? [1 - 9] | 1[0 - 2])$
一个月的31天(01~09和1~31): ^ ((0 ? [1 - 9]) | ((1 | 2)[0 - 9]) | 30 | 31)$
xml文件: ^ ([a - zA - Z] + -? ) + [a - zA - Z0 - 9] + \\.\[x | X]\[m | M][l | L]$
中文字符的正则表达式:[\u4e00 - \u9fa5]
双字节字符:\[^ \x00 - \xff](包括汉字在内,可以用来计算字符串的长度(一个双字节字符长度计2,ASCII字符计1))
空白行的正则表达式:\n\s * \r(可以用来删除空白行)
HTML标记的正则表达式:<(\S* ? )[^ > ] *>.* ? < / \1> | <.* ? / > (复杂的嵌套标记依旧无能为力)
首尾空白字符的正则表达式: ^ \s * | \s * $或(^ \s*) | (\s * $) (可以用来删除行首行尾的空白字符(包括空格、制表符、换页符等等))
腾讯QQ号:\[1 - 9][0 - 9]{ 4, } (腾讯QQ号从10000开始)
中国邮政编码:[1 - 9]\d{ 5 }(? !\d) (中国邮政编码为6位数字)
IP地址:\d + \.\d + \.\d + \.\d + (提取IP地址时有用)
IP地址:((? : (? : 25[0 - 5] | 2[0 - 4]\\d | [01] ? \\d ? \\d)\\.) { 3 }(? : 25[0 - 5] | 2[0 - 4]\\d | [01] ? \\d ? \\d))

 三、正则表达式在C++中的应用

        1.匹配  bool regex_match(string str,regex reg);        

                匹配返回: true  不满足返回false

                ①匹配用户输入的邮箱

regex reg("^\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*$");
	string userName;
	while (1)
	{
		cout << "请输入一个邮箱:";
		cin >> userName;
		bool result = regex_match(userName, reg);
		if (result)
		{
			cout << "正确邮箱" << endl;
			break;
		}
	}

输入输出:

请输入一个邮箱:b19031822@njupt.com.cn
正确邮箱

        ②匹配某一个字符串(会区分大小写!)

    //正则匹配,一定是完全匹配
	string str = "ILoveyou1314";
	regex  reg("[a-z0-9]+");    //小写祖母或者数字多个
	if (regex_match(str, reg))
	{
		cout << "匹配" << endl;
	}
	else
	{
		cout << "不匹配" << endl;  //IL 不满足正则规则
	}

 输出:不匹配

        ③ 通过设置参数,设置不区分大小写字母

	//大小写问题 ,构造的时候可以忽略大小写
	string str = "ILoveyou1314";
	regex  reg("[a-z0-9]+");    //小写祖母或者数字多个
	regex reg2("[a-z0-9]+", regex_constants::icase);
	if (regex_match(str, reg2))
	{
		cout << "匹配" << endl;
	}
	else
	{
		cout << "不匹配" << endl;  //IL 不满足正则规则
	}

输出:匹配

         ④字符串也可以直接充当正则规则(必须一一对应!!!)

	//字符串也可以直接充当正则规则
	string str = "ILoveyou1314";
	regex reg3("ILoveyou");
	if (regex_match(str, reg3))
	{
		cout << "匹配" << endl;
	}
	else
	{
		cout << "不匹配" << endl;  //1314
	}

输出:不匹配

        2. 正则替换string regex_replace(string str,regex reg, string newstr);

        注:并不会修改str原字符串

        ①正常匹配 (两种写法)

        法一:缺省,将匹配到的所有数字,都进行replace

    string  str = "ILoveyou1314520IMissyou520me";
	regex reg("\\d+");//匹配所有的数字!
	cout << "str:" << regex_replace(str, reg, "我爱你") << endl;
	cout << "oldstr:" << str << endl;

输出:

str:ILoveyou我爱你IMissyou我爱你me
oldstr:ILoveyou1314520IMissyou520me

        法二:传入传参的默认参数  regex_constants::format_default

    string  str = "ILoveyou1314520IMissyou520me";
    regex reg("\\d+");//匹配所有的数字!
    //默认方式
	cout << "default:" << regex_replace(str, reg, "我爱你", 
        regex_constants::format_default)<< endl;

输出: default:ILoveyou我爱你IMissyou我爱你me

        ②控制替换,仅替换第一次出现的  regex_constants::format_first_only

    string  str = "ILoveyou1314520IMissyou520me";
	regex reg("\\d+");//匹配所有的数字!
    //1.只替换第一次出现的
	cout << "only first:" << regex_replace(str, reg, "我爱你",                                 
         regex_constants::format_first_only<< endl;

输出:only first:ILoveyou我爱你IMissyou520me

         ③不拷贝方式(不返回与匹配内容无关的字段,相关的字段全部进行替换)                           regex_constants::format_no_copy        

    string  str = "ILoveyou1314520IMissyou520me";
	regex reg("\\d+");//匹配所有的数字!
	//2.不拷贝
	cout << "no copy:" << regex_replace(str, reg, "我爱你",
         regex_constants::format_no_copy)<< endl;

        3.截取处理字符串       

                ① 法一:bool regex_search(string str,smatch result,regex reg) 

                                                        不改变原字符串

    //正常截取处理 匹配项
	string str = "ILoveyou1314IMissyou520me";
	smatch result;
	bool flag = regex_search(str, result, regex("\\d+"));
	if (flag)
	{
		cout << "size:" << result.size() << endl;
		for (int i = 0; i < result.size(); i++)
		{
			cout << result.str() << endl;  //字符串
		}
		cout << "pre:" << result.prefix() << endl;
		cout << "suf:" << result.suffix() << endl;
	}
	cout << "str:" << str << endl;
	//匹配后面: result.suffix作为循环条件去持续截即可

输出:

size:1
1314
pre:ILoveyou
suf:IMissyou520me 

                ②法二:srgex_iterator

                      操作类似于istream_iterator 

    string str = "ILoveyou1314IMissyou520me";
    regex rule("\\d+");
	sregex_iterator pos(str.begin(), str.end(), rule);
	sregex_iterator end;   //end_of_iterator
	while (pos != end)
	{
		cout << pos->str() << endl;
		pos++;
	}
	//拆解字符串;

输出: 

1314
520

                ③法三:                                                                                                                           sregex_token_iterator(iterator begin,iteartor end,regex regex, int flag);

                                flag: 0: 所有匹配的,-1 存储所有不匹配的   

                                操作类似于istream_iterator 

    //sregex_token_iterator(iterator begin,iteartor end,regex regex, int flag);
	//flag: 0: 所有匹配的,-1 存储所有不匹配的
    string str = "ILoveyou1314IMissyou520me";
	regex regexRule("\\d+");
	sregex_token_iterator Begin(str.begin(), str.end(), regexRule, 0);
	sregex_token_iterator End;
	while (Begin != End)
	{
		cout << Begin->str() << endl;
		Begin++;
	}

输出:

1314
520 

                        

              

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_Ocean__

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值