1. 程式人生 > >c++ 正則表示式之差點過不去的坎

c++ 正則表示式之差點過不去的坎

 

bool Config::DecodeLine(const string & data) {
	string strT = "(string)";
	string intT = "(int)";
	string floatT = "(float)";
	string hexT = "(hex)";
	string binT = "(bin)";

	string blank = "(?:[ \\t]*)";
	string vName = "([_a-zA-Z][_0-9a-zA-Z]*)";

	string strVal = "(?:\"([^\"]*)\")";
	string strExp = "(?:" + strT + blank + vName + blank + "=" + blank + strVal + blank + ";)";

	string intVal = "([1-9][0-9]*|0)";
	string intExp = "(?:" + intT + blank + vName + blank + "=" + blank + intVal + blank + ";)";

	string binVal = "([01]{1,32})";
	string binExp = "(?:" + binT + blank + vName + blank + "=" + blank + binVal + blank + ";)";

	string hexVal = "([0-9A-F]{1,8})";
	string hexExp = "(?:" + hexT + blank + vName + blank + "=" + blank + hexVal + blank + ";)";

	string floatVal = "((?:[1-9][0-9]*|0)(?:\\.[0-9]*)?)";
	string floatExp = "(?:" + floatT + blank + vName + blank + "=" + blank + floatVal + blank + ";)";

	string allExp = "(?:" + strExp + "|" + intExp + "|" + floatExp + "|" + hexExp + "|" + binExp + ")";
	string note = "(?:#.*)";
	string line = "(?:" + blank + allExp + "?" + blank + note + "?" + "\n?)";

	regex pattern(line);

	smatch result;
	
	try {
		bool compileSuccess = regex_match(data, result, pattern);
	}
	catch (regex_error e) {
		cout << e.what() << "\ncode: " << e.code() << endl;
		return false;
	}


	if (!regex_match(data, result, pattern)) {
		printf("ERROR : The format is not correct.\nSyntax is : \n%s\n", syntax.c_str());
		return false;
	}
	
	vector<int> idxVec;
	 
	for (size_t i = 1; i < result.size(); i++) {
		if (result[i].str().size() > 0)
			idxVec.push_back(i);
		
	}
	for (size_t i = 0; i < idxVec.size(); i += 3) {
		size_t idx = idxVec[i];
		string type = result[idxVec[i]].str();
		string varName = result[idxVec[i + 1]].str();
		string valueStr = result[idxVec[i + 2]].str();
		cout << idxVec.size() << endl;
		if (type == "string") {
			printf("Config: string %s = \"%s\"\n", varName.c_str(), valueStr.c_str());
			strDirectory.Register(varName, valueStr);
		}
		else if (type == "float") {
			istringstream iss(valueStr);
			float val;
			iss >> val;
			printf("Config: float %s = %f\n", varName.c_str(), val);
			floatDirectory.Register(varName, val);
		}
		else if (type == "int") {
			istringstream iss(valueStr);
			int val;
			iss >> val;//數字存到val中了
			printf("Config: int %s = %d\n", varName.c_str(), val);
			
			intDirectory.Register(varName, val);
		}

regex pattern(line);正則表示式模板

smatch result;例項化匹配器

regex_match(data, result, pattern)確定匹配項


捕獲組就是把正則表示式中子表示式匹配的內容,
儲存到記憶體中以數字編號或顯式命名的組裡,
方便後面引用。當然,這種引用既可以是在正則表示式內部,
也可以是在正則表示式外部。一般一個小括號括起來就是一個捕獲組。
捕獲組可以進行巢狀。以深度優先進行編號,在js中編號從1開始。

?:是非捕獲組,匹配但不儲存

高能:result.size()是包含所有捕獲(注意不是非捕獲)的包含非空或空,line中blank不是需要的,strexp有三個,如果不滿足則到intexp,以此類推

string allExp = "(?:" + strExp + "|" + intExp + "|" + floatExp + "|" + hexExp + "|" + binExp + ")";

str表示式結果在1,2,3
int表示式結果在4,5,6
float 7,8,9
hex 10,11,12
bin 13,14,15

比如我識別bin,除了bin還有4個其他type在bin前邊,每個type會有3個捕獲,但都為空
最終bin表示式的idx在13,14,15

另外捕獲順序是這樣的:

 idxVec.size()是捕獲中非空的,

在這裡為3


istringstream是將文字讀入,例項化物件iss將內容傳遞給val中,注意使用的是>>