我有一个从VDF(阀门数据格式)转换而来的JSON字符串,正则表达式如下:
{"items_game": {
"prefabs": {
...
"coupon_crate_prefab": {
"prefab": "weapon_case_base",
"item_type": "coupon_crate",
"attributes": {
"cannot trade": "1"
},
"capabilities": {
"can_delete": "0"
},
"attributes": {
"expiration date": {
"attribute_class": "expiration_date",
"force_gc_to_generate": "1",
"use_custom_logic": "expiration_period_days_from_now",
"value": "2"
}
}
},
"coupon_key_prefab": {
"prefab": "csgo_tool",
"item_type": "coupon_key",
"attributes": {
"cannot trade": "1"
},
"capabilities": {
"can_delete": "0"
},
"attributes": {
"expiration date": {
"attribute_class": "expiration_date",
"force_gc_to_generate": "1",
"use_custom_logic": "expiration_period_days_from_now",
"value": "2"
}
}
}
...
}
}
想要的结果:
"coupon_key_prefab": {
"prefab": "csgo_tool",
"item_type": "coupon_key",
"attributes": {
"cannot trade": "1",
"expiration date": {
"attribute_class": "expiration_date",
"force_gc_to_generate": "1",
"use_custom_logic": "expiration_period_days_from_now",
"value": "2"
}
},
"capabilities": {
"can_delete": "0"
}
}
正如您所看到的,attributes
有重复项,我需要合并它们,因为它在JSON中是无效的
我该怎么做?(可能带有preg_replace)
使用regex这样做是一个非常糟糕的主意,因为JSON是一种可以通过多种方式格式化的数据结构,并且可以执行嵌套等操作。
这使得使用正则表达式进行解析成为一个坏主意,因为如果这样做,最多只能创建脆弱的代码。
但我也不确定这样做的有效性——如果你通过验证器运行JSON,重复的密钥会相互覆盖。
use strict;
use warnings;
use JSON;
local $/;
print to_json ( from_json ( <DATA>) , { pretty => 1 } );
__DATA__
{
"items_game": {
"prefabs": {
"coupon_crate_prefab": {
"prefab": "weapon_case_base",
"item_type": "coupon_crate",
"attributes": {
"cannot trade": "1"
},
"capabilities": {
"can_delete": "0"
},
"attributes": {
"expiration date": {
"attribute_class": "expiration_date",
"force_gc_to_generate": "1",
"use_custom_logic": "expiration_period_days_from_now",
"value": "2"
}
}
}
}
}
}
这将解析你的JSON,我希望我已经修复了它,以匹配你的源代码——请注意,它是你数据中"被破坏"的一部分。我认为这是大多数解析库中的常见行为。因此,这实际上可能意味着你的"事情"正以同样的方式被"处理"。
http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf
因此,很难给你一个确切的答案,告诉你如何最好地处理这个问题。理想情况下,您将使用JSON解析器,但您正在做的事情并没有在JSON规范中定义,因此您将获得可变的结果。
编辑:根据注释-似乎VDF类似于JSON,但不完全相同。
我仍然不会使用正则表达式,但可能会尝试递归解析。关闭{
并"传递"类似JSON的内容,这样您就可以获得命名键值对的底部分支,然后可以对其进行哈希处理。
如果仍然没有更好的答案,我可以稍后再编写一个perl示例(对不起,现在没有时间)。
你可以在这里找到一些可以使用的东西:http://www.perlmonks.org/?node_id=995856
但这也可能是为什么不正则表达式的一个很好的例子:)
好吧,您要求使用regex。有可能吗?也许,如果您感兴趣的属性中有有限数量的嵌套元素。这是个好主意吗?编号
(?<='"attributes'":) ('{(?:(?:[^{]*?'{(?:[^{]|'n)*?'}[^{]*?)+|(?:[^{]|'n)*?)})
将提取所有属性数据,并处理属性中的一级嵌套参数,如图所示https://regex101.com/r/rC3eK4/6。
由于您在示例中只有1个级别,因此效果非常好。如果你想有2个级别,你必须通过添加2个级别等选项来修改它,以保持所有{}
的完整性。可能有更好的方法来解决括号式正则表达式问题,但它绝对不是最好的工具。