C++ 使用正则表达式拆分字符串

今天做到一道题,给定一个类似于广义表的字符串(aaaa(bbbb(cccc,dddd),eeee(ffff))),表明的是各个人的层次关系。比如aaaa是bbbb和eeee的领导,bbbb是cccc和dddd的领导,现输入一个名称,比如ffff,要求输出其领导关系输出:aaaa>eeee>ffff

对于这样一个字母与括号混合在一起的字符串,我首先想到要对其进行拆分。不过字符串拆分的场景有很多,如果仅仅针对这一个问题,未免有些浪费,不如写一个较为通用的方法。于是想到尝试利用正则表达式进行拆分。

要匹配由字母组成的姓名很简单,由一个或多个大小写字母组成,即regex reg("[a-zA-Z]+");

常用到的函数有两个:

函数功能
bool regex_match(s,reg)字符串 s与表达式reg是否完全匹配(注意是完全匹配)
bool regex_search(s,M,reg)字符串s中是否有子串与表达式reg匹配,结果对象存储在M中

接下来详细解释下这个 “ M ”。

引用了https://zh.cppreference.com/w/cpp/regex/regex_search

其类型为smatch,即smatch M;
若不存在该子串(匹配失败):

方法返回值
M.ready()true
M.empty()true
M.size()0

若存在该子串:

方法返回值
M.ready()true
M.empty()false
M.size()有标记子表达式的数量加 1 ,即 1+e.mark_count()
M.prefix()前缀字符串
M.prefix().first指向 该匹配成功的子串 的前缀 的第一个字符的 迭代器
M.prefix().second指向 该匹配成功的子串 的前缀 的最后一个字符的下一个字符 的迭代器
M.suffix()后缀字符串
M.suffix().first同上,这个是后缀
M.suffix().second同上,这个是后缀
M[0].first指向匹配序列的首字符 的迭代器
M[0].second指向匹配数列的结尾后下一个字符 的迭代器
M[0].matchedtrue
M[n].first匹配有标记子表达式 n 的序列的起始,或若子表达式不参与匹配则为 last
M[n].second匹配有标记子表达式 n 的序列的结尾,或若子表达式不参与匹配则为 last
M[n].matched若子表达式 n 参与匹配则为 true ,否则为 false

终于介绍完了,下面是代码:
我想到的是用递归的方法实现划分(divide)函数:

  1. 调用regex_search方法,若匹配成功:
    1. 将前缀中所有非,的字符放入vector
    2. 将匹配的字符放入vector
    3. 对后缀调用divide方法
  2. 若匹配失败(当前串中已无要匹配的子串):
    1. 将当前串所有字符放入vector
#include <iostream>
#include <string>
#include <vector>
#include <regex>
using namespace std;

void divide(string s,vector<string> &v,regex reg)
{
	smatch mResult;
	if (regex_search(s, mResult, reg)) {
		for (auto it = mResult.prefix().first; it != mResult.prefix().second; it++) {
			if (*it == ',')
				continue;
			v.push_back(string(1, *it));
		}
		v.push_back(string(mResult[0].first, mResult[0].second));
		divide(mResult.suffix(), v, reg);
	}
	else {
		for (auto it = s.begin(); it != s.end(); it++)
			v.push_back(string(1, *it));
	}
}

int main()
{
	string source;
	vector<string> mid;
	cin >> source;
	regex reg("[a-zA-Z]+");
	divide(source, mid, reg);


	vector<string>::iterator it;
	for (it = mid.begin(); it != mid.end(); it++) {
		cout << *it << ' ';
	}
}

至于具体通用性如何,以后再修改吧哈哈

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值