我需要进行一些数据转换以实现数据负载兼容性。嵌套的键:值对需要展平,并将其组ID添加到每个子数据之前。
我一直试图理解该页面 Repeating a Capturing Group vs. Capturing a Repeated Group但似乎无法绕过它。
到目前为止我的表达:
//Swap the two rightmost consecutive bits that are different
for (int i = 0; i < 64; i++) {
if ((((x >> i) & 1) ^ ((x >> (i+1)) & 1)) == 1) {
// then swap them or flip their bits
int mask = (1 << i) | (1 << i + 1);
x = x ^ mask;
System.out.println("x = " + x);
return;
}
}
工作样本:https://regex101.com/r/Wobej7/1
我知道使用一个或多个中间步骤可以简化流程,但此时我想知道它是否可能。
源数据示例:
"(?'group'[\w]+)": {\n((\s*"(?'key'[^"]+)": "(?'value'[^"]+)"(?:,\n)?)+)\n},?
期望的转型:
"g1": {
"k1": "v1",
"k2": "v2",
"k3": "v3"
},
"g2": {
"k4": "v4",
"k5": "v5",
"k6": "v6"
},
"g3": {
"k7": "v7",
"k8": "v8",
"k9": "v9"
}
答案 0 :(得分:0)
第1步
搜索:
("[^"]+"):\s*{[^}]*},?\K
替换为\1
第2步
搜索:
(?:"[^"]+":\s*{|\G(?!\A))\s*("[^"]+"):\s*((?1))(?=[^}]*},?((?1)))(?|(,)|\s*}(,?).*\R*)
替换为:
{\3,\1,\2}\4\n
出于不同的原因,这不是一个单行的正则表达式解决方案。最重要的一点是我们既不能存储匹配的一部分供以后引用,也不能在PCRE中进行无限的观察。但幸运的是,大多数类似的问题可以分两步完成。
第一步应该是将组名移到{...}
块的末尾。这样,每次我们想要将匹配转换为单行输出时,我们都可以拥有组名。
("[^"]+"):\s*{[^}]*},?\K
(
开始捕获组#1
"[^"]+"
匹配群组名称)
CG#1结束:\s*{
群组名称应位于一堆其他角色之前[^}]*},?
我们必须进一步到块结束\K
扔掉目前匹配的所有内容我们在第一个捕获组中保留了我们的组名,并且必须用它替换整个匹配:
\1
现在这样一个块:
"g1": {
.
.
.
},
看起来像这样:
"g1": {
.
.
.
},"g1"
下一步是匹配每个块的键:值对,并在块的末尾捕获最近添加的组名。
(?:"[^"]+":\s*{|\G(?!\A))\s*("[^"]+"):\s*((?1))(?=[^}]*},?((?1)))(?|(,)|\s*}(,?).*\R*)
(?:
启动非捕获组
"[^"]+"
尝试匹配群组名称:\s*{
一个群组名称应该来自一堆其他角色|
或\G(?!\A)
从上一场比赛继续)
NCG结束\s*("[^"]+"):\s*((?1))
然后尝试匹配并捕获密钥:值对(?=[^}]*},?((?1)))
在块结束时同时匹配并捕获组名称(?|(,)|\s*}(,?).*\R*)
匹配剩余字符,例如逗号,大括号或换行符这种方式在每次成功试用正则表达式引擎时,我们有四个捕获的数据,他们的订单是关键:
{\3,\1,\2}\4\n
\3
组名(在块末尾添加的名称)\1
密钥\2
价值\4
逗号(可能在那里或可能没有)