【问题标题】:Make RegEx groups to split line into columns使 RegEx 组将行拆分为列
【发布时间】:2020-05-27 23:50:13
【问题描述】:

我在创建一些基于逗号的 RegEx 时遇到了麻烦。在下面的结构中,前 19 列应该只用逗号分隔,接下来的 3 列有 { } 但在这些括号内我可以有更多的括号(它是一个“脚本块”)。所以对于最后 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 列,而这 ([^\,]*), 将使我获得正确拆分的第一列,但也会干扰最后一列,所以我尝试将其“限制”到前 19 次出现,但如果我这样做 ([^\,]*),{19} 它将无法工作

我将如何做到这一点?

【问题讨论】:

  • 如果脚本块中有任意代码,Regex 可能无法解析它。自定义解析器似乎是必要的。
  • 仅供参考,Perl 事情没有做注意。 2 号 JS 不在正则表达式中进行递归! --!> have { } but inside these brackets I can have more brackets 需要 balance 括号。也不能使用平衡解析语言语法是吗?引号,评论,东西隐藏 obvuscert
  • 如果您的数据是正确的 CSV 格式(您的示例不是),您可以使用 CSV 解析器,例如:github.com/peterthoeny/parse-csv-js

标签: javascript regex regex-group


【解决方案1】:

使用替换和拆分的组合来完成此任务的方法不止一种:

  1. 暂时替换{...}中的逗号,按逗号分割,恢复每个数组项中的逗号
  2. 以逗号分隔,然后将数组项从第一次出现的{ 到最后一次出现的} 组合起来,跟踪嵌套
  3. 使用负前瞻进行拆分以避免{...} 内的逗号拆分

这是第一个选项的示例,我们暂时替换 {...} 中的逗号:

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() 将不可打印的字符恢复为逗号

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-03
    • 2016-02-19
    • 2023-02-08
    相关资源
    最近更新 更多