我正在将一个txt数据库文件写入sql转换器,我需要拆分行中的项目。问题是,在项目中可能存在可以包含多个逗号的脚本(这是db结构中的分隔符)。好消息是,脚本嵌套在{} -s中,因此,它使得工作类似于解析csv文件。唯一的问题是脚本本身可以容纳更多嵌套在{} -s中的脚本,这会阻止我的公式工作..
txt db的结构:
501,Red_Potion,Red Potion,0,50,,70,,,,,0xFFFFFFFF,7,2,,,,,,{ itemheal rand(45,65),0; },{},{}
502,Orange_Potion,Orange Potion,0,200,,100,,,,,0xFFFFFFFF,7,2,,,,,,{ itemheal rand(105,145),0; },{},{}
503,Yellow_Potion,Yellow Potion,0,550,,130,,,,,0xFFFFFFFF,7,2,,,,,,{ itemheal rand(175,235),0; },{},{}
504,White_Potion,White Potion,0,1200,,150,,,,,0xFFFFFFFF,7,2,,,,,,{ itemheal rand(325,405),0; },{},{}
正则表达式用于匹配拆分的分隔符:
,(?![^{}]*\})
这可以正常工作,直到它对抗一个更复杂的嵌套脚本项,如:
1492,Velum_Glaive,Vellum Glaive,4,20,,4500,250,,3,0,0x00004082,7,2,34,4,95,1,5,{ bonus2 bAddRace,RC_DemiHuman,80; if(getrefine()>=6) { bonus2 bSkillAtk,"LK_SPIRALPIERCE",100; bonus2 bSkillAtk,"KN_SPEARBOOMERANG",50; } if(getrefine()>=9) { autobonus2 "{ bonus bShortWeaponDamageReturn,20; bonus bMagicDamageReturn,20; }",100,2000,BF_WEAPON|BF_MAGIC,"{ specialeffect2 EF_REFLECTSHIELD; }"; } },{},{}
那么如何让它只匹配数据库结构分隔符并在脚本中保留逗号?
提前致谢! :)
答案 0 :(得分:1)
这不是正则表达式的工作。正如我在评论中指出的那样,嵌套结构通常超出了正则表达式的作用。 PCRE具有递归构造(?R)
并且.NET具有平衡组,但解决方案通常变得非常难以理解且无法维护。
除此之外,您不仅需要考虑{}
,还需要考虑脚本和注释。你手心解决这个问题要好得多。这是一个快速而肮脏的例子,它是如何使用PHP完成的(忽略字符串和注释!):
$level = 0;
$values = array();
$start = 0;
for($i = 0; $i < strlen($str); $i++)
{
switch($str[$i])
{
case ",":
if(!$level) {
$values[] = substr($str, $start, $i-$start);
$start = $i+1;
}
break;
case "{":
$level++;
break;
case "}":
$level--;
if($level < 0) trigger_error("unexpected }");
break;
}
}
if($level > 0) trigger_error("missing }");
$values[] = substr($str, $start);
您已经可以看到,您基本上最终会得到一个更简单的脚本解析器。