使用正则表达式模拟读写INI文件
生活随笔
收集整理的這篇文章主要介紹了
使用正则表达式模拟读写INI文件
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
#include "stdio.h"
#include <sstream>
#include <iostream>
#include <fstream>
#include <regex>
using namespace std;void Trim(char * str);
void lTrim(char * str);
void rTrim(char * str);// 測試sscanf 和 正則表達(dá)式
// sscanf提供的這個(gè)擴(kuò)展功能其實(shí)并不能真正稱為正則表達(dá)式,因?yàn)樗臅鴮戇€是離不開%
// []表示字符范圍,{}表示重復(fù)次數(shù),^表示取非,*表示跳過。所以上面這個(gè)url的解析可以寫成下面這個(gè)樣子:
//
//char url[] = "dv://192.168.1.253:65001/1/1"
//
//sscanf(url, "%[^://]%*c%*c%*c%[^:]%*c%d%*c%d%*c%d", protocol, ip, port, chn, type);
//
//解釋一下
//先取得一個(gè)最長的字符串,但不包括字串 ://,于是protocol="dv\0";
//然后跳過三個(gè)字符,(%*c)其實(shí)就是跳過 ://
// 接著取一個(gè)字符串不包括字符串 : ,于是ip = 192.168.1.253,這里簡化處理了,IP就當(dāng)個(gè)字符串來弄,而且不做檢查
// 然后跳過冒號取端口到port,再跳過 / 取通道號到chn,再跳過 / 取碼流類型到type。// c語言實(shí)現(xiàn)上例
void test1()
{char url[] = "dv://192.168.1.253:65001/1/1";char protocol[10];char ip[17];int port;int chn;int type;sscanf(url, "%[^://]%*c%*c%*c%[^:]%*c%d%*c%d%*c%d", protocol, ip, &port, &chn, &type);printf("%s, %s, %d, %d, %d\n", protocol, ip, port, chn, type);
}// 讀取ini里某行字符串, 得到: hello world!
// 正常串1: -claim="hello world!"
// 正常串2: claim = "hello world!"
// 正常串3: claim = " hello world!"
// 正常串4: claim_ = hello world!
// 正常串5: claim = "hello world!"
// 正常串6: claim = "hello world!"
// 正常串7: claim =
// 干擾串1: cl-aim = \"hello world!"
// 干擾串2: clai3m = "hello world!\"
// 干擾串3: cla_im = \\"hello world!\"
// 干擾串4: claim ='"hello world!\"
// 干擾串5: claim= @"\nhello world!"
// 干擾串6: claim=L"hello world!"
// 未處理1: claim[1] = 1
// 未處理1: claim[2] = 1void test2()
{char line[1000] = { 0 };char val[1000] = { 0 };char key[1000] = { 0 };FILE *fp = fopen("1.txt", "r");if (NULL == fp){printf("failed to open 1.txt\n");return ;}while (!feof(fp)){memset(line, 0, sizeof(line));fgets(line, sizeof(line) - 1, fp); // 包含了每行的\n printf("%s", line);Trim(line);// 提取等號之前的內(nèi)容memset(key, 0, sizeof(key));// sscanf使用的format不是正則表達(dá)式,不能用 \\s 表示各種空白符,即空格或\t,\n,\r,\fsscanf(line, "%[^ \t\n\r\f=]", key);//sscanf(line, "%*[^a-zA-Z0-9_-]%[^ \t\n\r\f=]", key);printf(" key: [%s]\n", key);// 提取等號之后的內(nèi)容memset(val, 0, sizeof(val));sscanf(line, "%*[^=]%*c%[^\n]", val); // 不包含了每行的換行符 Trim(val);printf(" val: [%s]\n", val);// 去除兩邊雙引號// ...// 插入map// map[key]=value;// string 轉(zhuǎn) 其它類型// atoi, atol, atof}printf("\n");fclose(fp);
}// 上例的C++實(shí)現(xiàn)
template<class T1, class T2>
inline T1 parseTo(const T2 t)
{static stringstream sstream;T1 r;sstream << t;sstream >> r;sstream.clear();return r;
}string trim(string& s)
{if (s.empty()) return s;for (int i = 0; i < s.size(); i++){if (s[i] != ' ' && s[i] != '\t' &&s[i] != '\n' && s[i] != '\r' && s[i] != '\f'){s.erase(0, i);break;}}for (int i = s.size() - 1; i > -1; i--){if (s[i] != ' ' && s[i] != '\t' &&s[i] != '\n' && s[i] != '\r' && s[i] != '\f'){s.erase(i + 1);break;}}return s;
}void test3()
{char val[1000] = { 0 };char key[1000] = { 0 };ifstream fin("1.txt");string line;if (fin){while (getline(fin, line)) // line中不包括每行的換行符 {cout << line << endl;/// 提取等號之前的內(nèi)容// 第1組()表示任意個(gè)空格字符,第2組()表示單詞(可帶_或-),// 第3組()表示1個(gè)以上的空格字符(或=),最后以任意字符串結(jié)尾regex reg("^([\\s]*)([\\w\\-\\_]+)([\\s=]+).*$"); // 取第2組代替原串string key = regex_replace(line, reg, "$2");cout << " key: {" << key << "}" << endl;/// 提取等號之后的內(nèi)容// 第1組()表示任意個(gè)空格字符,第2組()表示單詞(可帶_或-),// 第3組()表示1個(gè)以上的空格字符(或=),第4組()表示任意個(gè)字符除換行符外,// 第5組()表示以任意個(gè)空格字符(或回車換行符)結(jié)尾。reg = regex("^([\\s]*)([\\w\\-\\_]+)([\\s=]+)(.*)([\\s]*)$");// 取第4組代替原串string val = trim(regex_replace(line, reg, "$4"));cout << " val: {" << val << "}" << endl;// 去除兩邊雙引號// ...// 插入map// map[key]=value;// string 轉(zhuǎn) 其它類型// int i = parseTo<int>("123");// float f = parseTo<float>("1.23");// string str = parseTo<string>(123);}}else // 沒有該文件 {cout << "no such file" << endl;}
}void main()
{//test1();test2();test3();
}void lTrim(char * str)
{int i, len;len = strlen(str);for (i = 0; i<len; i++){if (str[i] != ' ' && str[i] != '\t' && str[i] != '\n' && str[i] != '\r' && str[i] != '\f') break;}memmove(str, str + i, len - i + 1);return;
}void rTrim(char * str)
{int i, len;len = strlen(str);for (i = len - 1; i >= 0; i--){if ((str[i] != ' ') && (str[i] != 0x0a) && (str[i] != 0x0d) && (str[i] != '\t') && (str[i] != '\f')) break;}str[i + 1] = 0;return;
}void Trim(char * str)
{int i, len;//先去除左邊的空格len = strlen(str);for (i = 0; i<len; i++){if (str[i] != ' ' && str[i] != '\t' && str[i] != '\n' && str[i] != '\r' && str[i] != '\f') break;}memmove(str, str + i, len - i + 1);//再去除右邊的空格len = strlen(str);for (i = len - 1; i >= 0; i--){if (str[i] != ' ' && str[i] != '\t' && str[i] != '\n' && str[i] != '\r' && str[i] != '\f') break;}str[i + 1] = 0;return;
}
/*
void Trim(char * str)
{lTrim(str);rTrim(str);
}
*/
總結(jié)
以上是生活随笔為你收集整理的使用正则表达式模拟读写INI文件的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux script 命令
- 下一篇: 2017 年热门编程语言排行榜,你的语言