使 RegEx 分组以将行拆分为列
Make RegEx groups to split line into columns
我在创建一些基于逗号的正则表达式时遇到了问题。在下面的结构中,前 19 列应该只用逗号分隔,接下来的 3 列有 { }
但在这些括号内我可以有更多的括号(它是 "script block")。所以对于最后 3 个,我想把所有东西都放在 ,{}
里面
这是结构
ID,AegisName,Name,Type,Buy,Sell,Weight,ATK[:MATK],DEF,Range,Slots,Job,Class,Gender,Loc,wLV,eLV[:maxLevel],Refineable,View,{ Script },{ OnEquip_Script },{ OnUnequip_Script }
以此为例
1624,Lich_Bone_Wand,Lich's Bone Wand,5,20,,800,60:170,,1,2,0x00018314,18,2,2,3,70,1,10,{ bonus bInt,1; bonus bDex,1; bonus bAtkEle,Ele_Undead; .@r = getrefine(); bonus3 bAutoSpellWhenHit,"NPC_WIDECURSE",5,10+.@r; if(.@r>=9){ bonus bMatkRate,3; bonus bMaxSP,300; } },{},{}
我找到了 ([^\,]*),"x(19)."(\{.*\}),"x(2)."(\{.*\})
,但它是用 Perl 编写的,我无法翻译成 JavaScript。我可以看到,如果我将 (\{.*\})
组合三次(像这样 (\{.*\}),(\{.*\}),(\{.*\})
,它会得到最后 3 列,而这个 ([^\,]*),
会得到第一列正确拆分但也会干扰最后一个,所以我尝试 "limiting" 它到前 19 次出现,但如果我这样做 ([^\,]*),{19}
它不会工作
我该如何完成?
有不止一种方法可以使用替换和拆分的组合来完成此操作:
- 暂时替换
{...}
中的逗号,按逗号拆分,恢复每个数组项中的逗号
- 以逗号分隔,然后组合从第一次出现的
{
到最后一次出现的 }
的数组项,跟踪嵌套
- 使用负前瞻进行拆分以避免在
{...}
中以逗号拆分
这是第一个选项的示例,我们暂时将 {...}
中的逗号替换为:
function properSplit(line) {
return line
.replace(/(\{[^,]*,.*?\})(?=,)/g, function(m, p1) {
return p1.replace(/,/g, '\x01');
})
.split(/,/)
.map(function(item) {
return item.replace(/\x01/g, ',');
});
}
var str = "1624,Lich_Bone_Wand,Lich's Bone Wand,5,20,,800,60:170,,1,2,0x00018314,18,2,2,3,70,1,10,{ bonus bInt,1; bonus bDex,1; bonus bAtkEle,Ele_Undead; .@r = getrefine(); bonus3 bAutoSpellWhenHit,\"NPC_WIDECURSE\",5,10+.@r; if(.@r>=9){ bonus bMatkRate,3; bonus bMaxSP,300; } },{},{}";
console.log(JSON.stringify(properSplit(str), null, ' '));
输出:
[
"1624",
"Lich_Bone_Wand",
"Lich's Bone Wand",
"5",
"20",
"",
"800",
"60:170",
"",
"1",
"2",
"0x00018314",
"18",
"2",
"2",
"3",
"70",
"1",
"10",
"{ bonus bInt,1; bonus bDex,1; bonus bAtkEle,Ele_Undead; .@r = getrefine(); bonus3 bAutoSpellWhenHit,\"NPC_WIDECURSE\",5,10+.@r; if(.@r>=9){ bonus bMatkRate,3; bonus bMaxSP,300; } }",
"{}",
"{}"
]
解释:
- 第一个
replace()
将 {...}
中的逗号替换为不可打印的字符 '\x01'
。它非贪婪地扫描到下一个 },
模式,其中 ,
是一个积极的先行
split()
现在缺少 {...}
中的逗号
map()
将不可打印的字符恢复为逗号
我在创建一些基于逗号的正则表达式时遇到了问题。在下面的结构中,前 19 列应该只用逗号分隔,接下来的 3 列有 { }
但在这些括号内我可以有更多的括号(它是 "script block")。所以对于最后 3 个,我想把所有东西都放在 ,{}
这是结构
ID,AegisName,Name,Type,Buy,Sell,Weight,ATK[:MATK],DEF,Range,Slots,Job,Class,Gender,Loc,wLV,eLV[:maxLevel],Refineable,View,{ Script },{ OnEquip_Script },{ OnUnequip_Script }
以此为例
1624,Lich_Bone_Wand,Lich's Bone Wand,5,20,,800,60:170,,1,2,0x00018314,18,2,2,3,70,1,10,{ bonus bInt,1; bonus bDex,1; bonus bAtkEle,Ele_Undead; .@r = getrefine(); bonus3 bAutoSpellWhenHit,"NPC_WIDECURSE",5,10+.@r; if(.@r>=9){ bonus bMatkRate,3; bonus bMaxSP,300; } },{},{}
我找到了 ([^\,]*),"x(19)."(\{.*\}),"x(2)."(\{.*\})
,但它是用 Perl 编写的,我无法翻译成 JavaScript。我可以看到,如果我将 (\{.*\})
组合三次(像这样 (\{.*\}),(\{.*\}),(\{.*\})
,它会得到最后 3 列,而这个 ([^\,]*),
会得到第一列正确拆分但也会干扰最后一个,所以我尝试 "limiting" 它到前 19 次出现,但如果我这样做 ([^\,]*),{19}
它不会工作
我该如何完成?
有不止一种方法可以使用替换和拆分的组合来完成此操作:
- 暂时替换
{...}
中的逗号,按逗号拆分,恢复每个数组项中的逗号 - 以逗号分隔,然后组合从第一次出现的
{
到最后一次出现的}
的数组项,跟踪嵌套 - 使用负前瞻进行拆分以避免在
{...}
中以逗号拆分
这是第一个选项的示例,我们暂时将 {...}
中的逗号替换为:
function properSplit(line) {
return line
.replace(/(\{[^,]*,.*?\})(?=,)/g, function(m, p1) {
return p1.replace(/,/g, '\x01');
})
.split(/,/)
.map(function(item) {
return item.replace(/\x01/g, ',');
});
}
var str = "1624,Lich_Bone_Wand,Lich's Bone Wand,5,20,,800,60:170,,1,2,0x00018314,18,2,2,3,70,1,10,{ bonus bInt,1; bonus bDex,1; bonus bAtkEle,Ele_Undead; .@r = getrefine(); bonus3 bAutoSpellWhenHit,\"NPC_WIDECURSE\",5,10+.@r; if(.@r>=9){ bonus bMatkRate,3; bonus bMaxSP,300; } },{},{}";
console.log(JSON.stringify(properSplit(str), null, ' '));
输出:
[
"1624",
"Lich_Bone_Wand",
"Lich's Bone Wand",
"5",
"20",
"",
"800",
"60:170",
"",
"1",
"2",
"0x00018314",
"18",
"2",
"2",
"3",
"70",
"1",
"10",
"{ bonus bInt,1; bonus bDex,1; bonus bAtkEle,Ele_Undead; .@r = getrefine(); bonus3 bAutoSpellWhenHit,\"NPC_WIDECURSE\",5,10+.@r; if(.@r>=9){ bonus bMatkRate,3; bonus bMaxSP,300; } }",
"{}",
"{}"
]
解释:
- 第一个
replace()
将{...}
中的逗号替换为不可打印的字符'\x01'
。它非贪婪地扫描到下一个},
模式,其中,
是一个积极的先行 split()
现在缺少{...}
中的逗号
map()
将不可打印的字符恢复为逗号