#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!
// 干擾串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] = 1
void 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,\f
sscanf(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)
templateclass T1, class T2>
inline T1 parseTo(const T2 t)
{
static stringstream sstream;
T1 r;
sstream t;
sstream >> r;
sstream.clear();
return r;
}
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\\r\\n]*)$");
// 取第4組代替原串
string val = regex_replace(line, reg, "$4");
cout " val: {" val "}" endl;
// 去除兩邊雙引號
// ...
// 插入map
// map[key]=value;
// string 轉(zhuǎn) 其它類型
// int i = parseToint>("123");
// float f = parseTofloat>("1.23");
// string str = parseTostring>(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; ilen; 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; ilen; 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);
}
*/
以上所述是小編給大家介紹的使用正則表達(dá)式(regex_replace)模擬讀取INI文件,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時(shí)回復(fù)大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!