将字符串解析为Javascript对象并向键添加唯一id
下面的代码接收字符串并将其转换为对象。问题是字符串包含多个重复的键,当转换为对象时,它只识别最后一个键 这是我的工作演示 这是我的密码:将字符串解析为Javascript对象并向键添加唯一id,javascript,json,parsing,object,Javascript,Json,Parsing,Object,下面的代码接收字符串并将其转换为对象。问题是字符串包含多个重复的键,当转换为对象时,它只识别最后一个键 这是我的工作演示 这是我的密码: var str = 'View\n{\n Name: View1;\n Image\n {\n BackgroundImage: Image.gif;\n Position: 0, 0;\n Width: 320;\n Height: 480;\n }\n\n But
var str = 'View\n{\n Name: View1;\n Image\n {\n BackgroundImage: Image.gif;\n Position: 0, 0;\n Width: 320;\n Height: 480;\n }\n\n Button\n {\n BackgroundImage: Button.gif;\n Transition: View2;\n Position: 49, 80;\n Width: 216;\n Height: 71;\n }\n\n Button\n {\n BackgroundImage: Button2.gif;\n Position: 65, 217;\n Width: 188;\n Height: 134;\n }\n\n Label\n {\n Position: 106, 91;\n Width: 96;\n Height: 34;\n Text: "Button";\n FontSize: 32;\n Color: 0.12549, 0.298039, 0.364706, 1;\n }\n Scroll\n {\n Position: 106, 91;\n Width: 96;\n Height: 34;\n Button{\n BackgroundImage: Button2.gif;\n Position: 65, 217;\n Width: 188;\n Height: 134;\n }\n Button{\n BackgroundImage: Button2.gif;\n Position: 65, 217;\n Width: 188;\n \n Height: 134;\n }\n\n }\n\n}';
str = str.replace(/(\w+)\s*\{/g, "$1:{"); // add in colon after each named object
str = str.replace(/\}(\s*\w)/g, "},$1"); // add comma before each new named object
str = str.replace(/;/g, ","); // swap out semicolons with commas
str = str.replace(/,(\s+\})/g, "$1"); // get rid of trailing commas
str = str.replace(/([\d\.]+(, [\d\.]+)+)/g, "[$1]"); // create number arrays
str = str.replace(/"/g, ""); // get rid of all double quotes
str = str.replace(/:\s+([^\[\d\{][^,]+)/g, ':"$1"'); // create strings
$("pre").html(str);
var obj;
eval("obj={" + str + "};");
下面是上面代码的输出。请注意,有多个“按钮”。问题就从这里开始
View:{
Name:"View1",
Image:{
BackgroundImage:"Image.gif",
Position: [0, 0],
Width: 320,
Height: 480
},
Button:{
BackgroundImage:"Button.gif",
Transition:"View2",
Position: [49, 80],
Width: 216,
Height: 71
},
Button:{
BackgroundImage:"Button2.gif",
Position: [65, 217],
Width: 188,
Height: 134
},
Label:{
Position: [106, 91],
Width: 96,
Height: 34,
Text:"Button",
FontSize: 32,
Color: [0.12549, 0.298039, 0.364706, 1]
},
Scroll:{
Position: [106, 91],
Width: 96,
Height: 34,
Button:{
BackgroundImage:"Button2.gif",
Position: [65, 217],
Width: 188,
Height: 134
},
Button:{
BackgroundImage:"Button2.gif",
Position: [65, 217],
Width: 188,
Height: 134
}
}
}
我想知道如何在每个键的末尾添加一个自动递增的数字,即视图、名称、按钮、图像等。您应该使用JSON库进行对象解析。这将大大简化事情 就数据结构而言,“按钮”、“标签”、“滚动”类型的对象应存储在数组中,键应位于字段中。我推荐这种类型。例如,您可以轻松地用JSON将数据表示为:
{
View:{
Name:"View1",
Objects: [
{
Type: "Image",
BackgroundImage:"Image.gif",
Position: [0, 0],
Width: 320,
Height: 480
},
{
Type: "Button",
BackgroundImage:"Button.gif",
Transition:"View2",
Position: [49, 80],
Width: 216,
Height: 71
},
{
Type: "Button",
BackgroundImage:"Button2.gif",
Position: [65, 217],
Width: 188,
Height: 134
},
{
Type: "Label",
Position: [106, 91],
Width: 96,
Height: 34,
Text:"Button",
FontSize: 32,
Color: [0.12549, 0.298039, 0.364706, 1]
},
{
Type: "Scroll",
Position: [106, 91],
Width: 96,
Height: 34,
Objects: [
{
Type: "Button",
BackgroundImage:"Button2.gif",
Position: [65, 217],
Width: 188,
Height: 134
},
{
Type: "Button",
BackgroundImage:"Button2.gif",
Position: [65, 217],
Width: 188,
Height: 134
}
]
}
}
}
请注意,此方法支持多个按钮对象
编辑 考虑到这些要求,我发现这是有效的。在替换任何字符串之前,添加
var i=0
并将其添加到最终正则表达式之后:
str=str.replace(/([^:]+):{/g,函数(m,p1){返回p1+“”+(++i).toString()+”:{;})
*这将以牺牲你的灵魂为代价给你想要的结果*
为您的格式编写简单的解析器/编码器并不困难。容器对象如下所示:
{type: "view", "properties":{"name":"View1"}, "objects":[{"type":"Image","properties":{...}, "objects":[...]}, ...]}
而且逻辑相对简单。对象由“[A-Za-z]+{”开始,由“}(,?)”关闭。属性由“[A-Za-z]:”开始,并且始终由“}”关闭。按照这些规则,应该不难迭代字符串中的字符,将每个字符追加到缓冲区,直到缓冲区与其中一个规则匹配。请参见此处:它们使用“code”url1.replace(/\d+$/,function(n){return++n});“code”,这与我使用的类似。我改为“code”str=str.replace(/\d+$/,函数(n){return++n})“code”但它不起作用。你知道我做错了什么吗?还有,我的永远不会以数字开头。我必须附加一个以1开头的数字。你肯定不想向对象的键添加递增的数字。你能解释一下为什么要这样做吗?我必须解决的问题是使对象的所有“键”都是唯一的。我必须保持与我发布的格式相同。目前,它正在删除除代码中的一个“按钮”之外的所有副本。在其上添加一个数字似乎是最好的选择,只要对象的结构没有改变,我肯定会找到更好的解决方案。也许我误解了它,但如果您添加一个将您的对象放入数组,而不是更改键?是的,我们已经检查过了,但这不是我们的选项。传入的字符串从来都不是json或任何对象。它是我们拥有的程序的指令脚本。我必须使用表单编辑其中的值。除了处理重复项。另一个问题是,当我们编辑完对象后,我必须将其还原为原始字符串格式并传回。我知道这并不理想,但……用修改后的答案编辑。它或多或少满足了你的需要。无论哪种方式,我都强烈建议不要走你要走的路。尽管它看起来很像,但你的输入字符串实际上是一个格式良好的序列化。正如我在编辑中所讨论的,编写一个简单的解析器/编码器应该很容易。谢谢。我在你的帖子中添加了一个编辑。我做了更改,但它抛出了一个错误。我不确定我是否做得正确。我将研究你推荐的方法,这也将需要大量修改其他代码。我们可能只是添加数字,进行更改,然后在完成后将其删除。此程序仅在编辑过程中控制对象,然后返回到其来源…希望有意义我猜编辑没有显示。以下是我编辑的内容:
i=0;str=str.replace(/(\w+)\s*\{/g,$1:{”);//在每个命名对象str=str.replace(/([\d\.]++(,[\d\.]+)/g,[$1]”)后添加冒号;//创建数字数组str=str.replace(/“/g)”;//去掉所有双引号//str=str.replace(/:\s+([^\[\d\\\\[^,]+])/g',:“$1”);//创建字符串str replace(/:\s+([^\[\[\\[\\\\\\\\\\[^]+]g])/g),函数(m,p1+++++i:“+p1;});//创建字符串
再次检查它(包括说明),并确保您定义了i。在反复检查我正在做的事情后,我不得不编辑两次(对不起,现在是凌晨3点)。从长远来看,解析器可能会为您省去很多麻烦,而且可能不会像您所想的那样花费太多时间来重新编写其他内容,但我理解GSD的必要性。