适合配置的验证方案

//
// 配置格式:I32|<1,2,3> -> int32 类型,值在1、2、3中枚举
//           I64|[1,100] -> int64 类型,值在[1,100]范围内(全闭区间)
//           F32|(1.0,11.9) -> float 类型,值在(1.0,11.9)范围内(全开区间)
//           S10|^[a-zA-Z][A-Za-z0-9_.|]{2,}$ -> string 类型,长度不大于10,用^[a-zA-Z][A-Za-z0-9_.|]{2,}$的正则规则
//
#include <regex>
#include <iostream>
#include <string>
#include <map>

class CArgConstraint
{
	typedef std::pair<char, char> fuhao; // [ ( ) ] 这些符号
	typedef std::pair<fuhao, std::pair<float, float> > pairFloatValue;
	typedef std::pair<fuhao, std::pair<int, int> > pairInt32Value;
	typedef std::pair<fuhao, std::pair<long long, long long> > pairInt64Value;

private:
	std::map<std::string, pairFloatValue> m_mapFloat;    // title, 值
	std::map<std::string, pairInt32Value> m_mapInt32;
	std::map<std::string, pairInt64Value> m_mapInt64;
	std::map<std::string, std::string>    m_mapString;   // title, 正则
	std::map<std::string, std::vector<int> > m_mapEnum;    // title, enum(只支持int, 其他可考虑用模板)

public:
	CArgConstraint(){}

	template<typename T>
	bool IsArgConstratint(const char* titel, const T& value)
	{
		std::cout << "T error" << std::endl;
		return false;
	}
	template<>
	bool IsArgConstratint<int>(const char* titel, const int& value)
	{
		std::map<std::string, pairInt32Value>::iterator itSub = m_mapInt32.find(titel);
		if (itSub != m_mapInt32.end())
		{
			switch (itSub->second.first.first)
			{
			case '(':
				if (value <= itSub->second.second.first)
					return false;
				break;
			case '[':
				if (value < itSub->second.second.first)
					return false;
				break;
			default:
				return false;
			}

			switch (itSub->second.first.second)
			{
			case ')':
				if (value >= itSub->second.second.second)
					return false;
				break;
			case ']':
				if (value > itSub->second.second.second)
					return false;
				break;
			default:
				return false;
			}
			return true;
		}
		return false;
	}
	template<>
	bool IsArgConstratint<long long>(const char* titel, const long long& value)
	{
		// core like IsArgConstratint<int>
		return false;
	}
	template<>
	bool IsArgConstratint<float>(const char* titel, const float& value)
	{
		// core like IsArgConstratint<int>
		return false;
	}
	template<>
	bool IsArgConstratint<std::string>(const char* titel, const std::string& value)
	{
		std::map<std::string, std::string>::iterator it = m_mapString.find(titel);
		if (it != m_mapString.end())
		{
			// 用传进来的正则规则判断
			const std::regex pattern(value.c_str());
			if (std::regex_match(value, pattern))
				return true;
		}
		return false;
	}
	template<>
	bool IsArgConstratint<std::vector<int> >(const char* titel, const std::vector<int>& value)
	{
		std::map<std::string, std::vector<int> >::iterator it = m_mapEnum.find(titel);
		if (it != m_mapEnum.end())
		{
			if (value.size() == 1)
			{
				std::vector<int>::iterator itSub = std::find(it->second.begin(), it->second.end(), value[0]);
				if (itSub != it->second.end())
					return true;
			}
		}
		return false;
	}
};

std::string format_data(const std::string& data)
{
	// is int
	const std::regex patternInt("^[0-9]*$");
	const std::regex patternFloat("^(-?[0-9]+)(\\.[0-9]+)?");
	const std::regex patternStr("^[a-zA-Z][A-Za-z0-9_.|]{2,}$");
	if (std::regex_match(data, patternInt))
		return "int";
	else if (std::regex_match(data, patternFloat))
		return "float";
	else if (std::regex_match(data, patternStr))
		return "string";
	return "NULL";
}

// 解析配置的范围
bool zhengze(const std::string& str)
{
	// 类型|范围
	const std::regex patternFenGe("(I32|I64|F32)\\|(\\[|\\()(\\d*\\.?\\d+),(\\d*\\.?\\d+)(\\]|\\))");
	std::match_results<std::string::const_iterator> result;

	bool valid = std::regex_match(str, result, patternFenGe);
	if (valid)
	{
		std::cout << "[xx]" << result[0] << std::endl;  // 没用
		std::cout << "[0]" << result[1] << std::endl;   // | 前面
		std::cout << "[1]" << result[2] << std::endl;   // [ (
		std::cout << "[2]" << result[3] << std::endl;   // 第一个数字
		std::cout << "[3]" << result[4] << std::endl;   // 第二个数字
		std::cout << "[4]" << result[5] << std::endl;   // ] )

		return true;
	}
	// 类型|枚举
	const std::regex patternEnum("(I32|I64|F32)\\|<(.+)>"); // ("I32|I64|F32\\|<(.+)>"); // "(I32|I64|F32)\\|(<)((\\d*\\.?\\d+),?)(>)");
	valid = std::regex_match(str, result, patternEnum);
	if (valid)
	{
		std::string strTemp;
		int iCount = result.size();
		for (int i = 0; i < iCount; ++i)
		{
			std::cout << "[" << i << "]" << result[i] << std::endl;
			if (i == 2)
				strTemp = result[i];
		}

		const std::regex partternSub("(\\d*\\.?\\d+),?");
		std::sregex_iterator it(strTemp.begin(), strTemp.end(), partternSub);
		std::sregex_iterator end;

		for (; it != end; ++it)
		{
			std::cout << (*it)[1].str() << std::endl;
		}

		return true;
	}
	// 类型|正则表达式
	const std::regex patternStr("(S[1-9][0-9]{0,})\\|(.+)");
	// std::match_results<std::string::const_iterator> result;

	valid = std::regex_match(str, result, patternStr);
	if (valid)
	{
		std::cout << "[xx]" << result[0] << std::endl;  // 没用
		std::cout << "[0]" << result[1] << std::endl;   // | 前面
		std::cout << "[1]" << result[2] << std::endl;   // 正则
		return true;
	}

	return false;
}

int main()
{
	std::string date1 = "2014";
	std::string date2 = "12.08";
	std::string date3 = "12.a8";
	std::string date4 = "Abc_.123fff";
	std::string date5 = "A";

	std::cout << date1 << " == " << format_data(date1) << std::endl;
	std::cout << date2 << " == " << format_data(date2) << std::endl;
	std::cout << date3 << " == " << format_data(date3) << std::endl;
	std::cout << date4 << " == " << format_data(date4) << std::endl;
	std::cout << date5 << " == " << format_data(date5) << std::endl;

	std::string str01 = "I32|<1,2,3>";
	std::string str02 = "I64|[1,100]";
	std::string str03 = "F32|(2.0,200.3]";
	std::string str04 = "F32|[3,300)";
	std::string str05 = "I32|(4,500)";
	std::string str06 = "S40|^[a-zA-Z][A-Za-z0-9_.|]{2,}$";
	
	zhengze(str01);
	zhengze(str02);
	zhengze(str03);
	zhengze(str04);
	zhengze(str05);
	zhengze(str06);

	CArgConstraint cc;
	int xx = 9;
	cc.IsArgConstratint("abc", xx);
	float yy = 9;
	cc.IsArgConstratint("abc", yy);
	double dd = 9;
	cc.IsArgConstratint("abc", dd);

	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值