C/C++ code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static const char* parse_test[] =
{
"[{\"iconNo\":\"1\",\"seq\":\"1\",\"devStatus\":\"1\",\"devdescribe\":\"asd\"}]",
"[{\"iconNo\":\"2\",\"seq\":\"2\",\"devStatus\":\"2\",\"devdescribe\":\"asasdsasdas师大d\"}]"
};
int parse_key_value(const char *line)
{
// 主要检查以下不合法性:
//1, key或者value没有被'"'包裹
//2, ""内没有空白字符
//3, key : value 形式不合法
int key_start, dot, key_end, val_start, val_end;
int line_len;
int state = 0; //0:初始化,1:解析key,2:解析',',3:解析val,4:解析',' or '\0'
//or }]序列
int left_over = 0;
char key[20], value[30];
key_start = dot = key_end = val_start = val_end = -1;
line_len = strlen(line);
for (int i = 0; i <= line_len; /*<=line_len目的: 对','和'\0'同等对待*/)
{
switch (state)
{
case 0:
{
switch (line[i])
{
case ' ':
case '\t':
{
++i;
}break;
case '[':
{
// 多余的[
if (left_over != 0)
{
return -1;
}
if (line[i+1] != '{')
{
return -1;
}
left_over++; //左侧"[{"序列合法
i+=2;
}break;
case '{': //不应该单独出现,此分支可以不写,被default处理
{
return -1;
}break;
case '"':
{
if (left_over == 0)
{
//还没遇到[{序列
return -1;
}
// key的左'"',记录key_start
key_start = ++ i;
++ state; //进入解析key状态
}break;
default:
{
// 非空白字符 or 非[{序列 or 非'"' or '\0'
return -1;
};
}
}break;
case 1:
{
switch (line[i])
{
case ' ':
case '\t':
case '{':
case '[':
case ',':
case ':':
case '\0':
{
// key不应该包含非字母,这里只列举一些
return -1;
}break;
case '"':
{
//key结束,记录key_end
key_end = i-1;
if (key_end < key_start) //key为空
{
return -1;
}
++ i;
state ++; // 进入解析':'状态
}break;
default:
{
// 任意合法字母
++ i;
}break;
}
}break;
case 2:
{
switch (line[i])
{
case '\t':
case ' ':
{
// 空白字符掠过
++ i;
}break;
case ':':
{
//找到':'
dot = i++;
state++;
//向后掠过所有的空白,检测"val的'"'
while (line[i] != '\0')
{
if (line[i] != ' ' && line[i] != '\t')
{
if (line[i] != '"')
{
return -1; //遇到非空白非"字符
}
val_start = ++ i;
break;
}
++ i;
}
if (val_start == -1)
{
return -1;
}
}break;
default:
{
//非合法,出错
return -1;
}break;
}
}break;
case 3: //开始解析value
{
switch (line[i])
{
//val内不应该有非字母字符
case '\t':
case ' ':
case ',':
case '\0':
case '[':
case '}':
case ']':
case '{':
{
return -1;
}break;
case '"':
{
val_end = i - 1;
if (val_end < val_start)
{
return -1;
}
++ i;
state++;
}break;
default:
{
++ i; //正常字母
}break;
}
}break;
case 4: //最后阶段:如果是line末尾需要检测}]
//不是line末尾需要检测',',并且重新进入state = 1
{
// 直接快速的处理过去
while (line[i] == ' ' || line[i] == '\t')
{
++ i;
}
if (line[i] == '\0')
{
return -1; // line末尾,却没有}]
}
if (line[i] == ',')
{
// 一个字段结束,打印key,value
strncpy(key, line + key_start, key_end - key_start + 1);
key[key_end - key_start + 1] = '\0';
strncpy(value, line + val_start, val_end - val_start + 1);
value[val_end - val_start + 1] = '\0';
printf("%s:%s\n", key, value);
key_start = key_end = val_start = val_end = -1;
// 向后找到value的"
while (line[++i] != '\0' && (line[i] == ' ' || line[i] == '\t'));
if (line[i] != '"')
{
return -1; // , 之后非",错误
}
key_start = ++ i;
state = 1; //直接进入解析value状态
}
else if (line[i] == '}')
{
if (line[i+1] != ']')
{
return -1; //}]不完整
}
strncpy(key, line + key_start, key_end - key_start + 1);
key[key_end - key_start + 1] = '\0';
strncpy(value, line + val_start, val_end - val_start + 1);
value[val_end - val_start + 1] = '\0';
printf("%s:%s\n", key, value);
return 0; //解析完毕,}]之后再有字符也不理会了
}
else
{
// 意外的字符
return -1;
}
}break;
default:
{
fprintf(stderr, "unknown state %d \n", state);
return -1;
}break;
}
}
}
int main()
{
char test_buffer[1000];
while (scanf("%s", test_buffer) == 1)
{
parse_key_value(test_buffer);
}
for (int i = 0; i < 2; ++ i)
{
parse_key_value(parse_test[i]);
}
return 0;
} |