Regex 用于拆分txt db文件的正则表达式

Regex 用于拆分txt db文件的正则表达式,regex,split,comma,separator,Regex,Split,Comma,Separator,我正在将一个txt数据库文件写入sql converter,我需要在行中拆分这些项。问题是,在这些项中,可能有一些脚本可以包含多个逗号(它们是数据库结构中的分隔符)。好消息是,脚本嵌套在{}-s中,因此,它使工作类似于解析csv文件。唯一的问题是,脚本本身可以容纳更多嵌套在{}-s中的脚本,这使我的公式无法工作 txt数据库的结构: 501,Red_Potion,Red Potion,0,50,,70,,,,,0xFFFFFFFF,7,2,,,,,,{ itemheal rand(45,65),

我正在将一个txt数据库文件写入sql converter,我需要在行中拆分这些项。问题是,在这些项中,可能有一些脚本可以包含多个逗号(它们是数据库结构中的分隔符)。好消息是,脚本嵌套在{}-s中,因此,它使工作类似于解析csv文件。唯一的问题是,脚本本身可以容纳更多嵌套在{}-s中的脚本,这使我的公式无法工作

txt数据库的结构:

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; },{},{}
我用于匹配用于拆分的delimeters的正则表达式:

,(?![^{}]*\})
这可以正常工作,直到它对更复杂的嵌套脚本项进行计数,如:

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; }"; } },{},{}
那么,我如何使它只匹配db结构delimeters,并在脚本中保留逗号呢


提前感谢!:)

这不是正则表达式的工作。正如我在评论中指出的,嵌套结构通常超出了正则表达式的功能。PCRE具有递归结构
(?R)
,而.NET具有平衡组,但解决方案通常变得非常不可读和不可维护

此外,您不仅需要考虑
{}
,还需要考虑脚本中的字符串和注释。你最好是手动解析这个东西。下面是一个使用PHP(忽略字符串和注释!)的快速而肮脏的示例:

$level=0;
$values=array();
$start=0;
对于($i=0;$i0)触发_错误(“缺失”);
$values[]=substr($str,$start);

您已经可以看到,您的脚本最终基本上使用了一个更简单的解析器。

这不是正则表达式的工作。正如我在评论中指出的,嵌套结构通常超出了正则表达式的功能。PCRE具有递归结构
(?R)
,而.NET具有平衡组,但解决方案通常变得非常不可读和不可维护

此外,您不仅需要考虑
{}
,还需要考虑脚本中的字符串和注释。你最好是手动解析这个东西。下面是一个使用PHP(忽略字符串和注释!)的快速而肮脏的示例:

$level=0;
$values=array();
$start=0;
对于($i=0;$i0)触发_错误(“缺失”);
$values[]=substr($str,$start);

您已经可以看到,您的脚本基本上使用了一个更简单的解析器。

嵌套结构是正则表达式方法经常出现故障的地方。根据您的正则表达式风格,您可能能够使用递归构造(PCRE)或平衡组(.NET),但解决方案通常会变得难看。您可能应该逐个字符手动遍历字符串,并计算大括号开头和结尾的嵌套级别。您可能可以使用快捷方式,但有非常具体的限制。如果嵌套脚本中从来没有
、{
}、
,那么可以非常轻松地使用lookaround。否则,正如@m.buettner指出的,这并不是regex的工作。另外,不要忘记脚本字符串中可能有不匹配的大括号。因此,实际上您甚至还必须计算脚本中的字符串和注释。嵌套结构是正则表达式方法通常出现故障的地方。根据您的正则表达式风格,您可能能够使用递归构造(PCRE)或平衡组(.NET),但解决方案通常会变得难看。您可能应该逐个字符手动遍历字符串,并计算大括号开头和结尾的嵌套级别。您可能可以使用快捷方式,但有非常具体的限制。如果嵌套脚本中从来没有
、{
}、
,那么可以非常轻松地使用lookaround。否则,正如@m.buettner指出的,这并不是regex的工作。另外,不要忘记脚本字符串中可能有不匹配的大括号。实际上,你甚至还需要计算脚本中的字符串和注释。实际上,我最终用特殊字符替换了脚本边框,并为此应用了正则表达式。虽然不是最好的,但代码中的改动最少:)@Angezerus是的,听起来是个不错的解决办法。。。只需小心使用包含这些字符的字符串;)实际上,我最终用特殊字符替换了脚本边框,并为此应用了正则表达式。虽然不是最好的,但代码中的改动最少:)@Angezerus是的,听起来是个不错的解决办法。。。只需小心使用包含这些字符的字符串;)
$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);