views:

120

answers:

2

hello, I'm currently writing a script editing app in c# to edit game scripts. I want to be able to load a script file and get the name of an NPC object and the script contents. The script looks like this:

INSTANCE PC_Thief(NPC_DEFAULT)

{
    //-------- primary data --------
    name    = "Diego";
    Npctype   = NPCTYPE_FRIEND;
    guild   = GIL_STT;
    level   = 999;   // real 25, aber 999 damit er nicht vor dem Troll flieht!
    voice   = 11;
    id    = 1;
    flags   = NPC_FLAG_IMMORTAL;

    //-------- visuals --------
    //       animations
    Mdl_SetVisual  (self,"HUMANS.MDS");
    //       Body-Mesh   Body-Tex Skin-Color Head-MMS    Head-Tex Teeth-Tex
    Mdl_SetVisualBody (self,"hum_body_Naked0",  0,   2,   "Hum_Head_Thief",  15,    4, STT_ARMOR_H);


    //--------- abilities --------
    attribute[ATR_STRENGTH]  = 70;
    attribute[ATR_DEXTERITY]  = 90;
    attribute[ATR_MANA_MAX]  = 0;
    attribute[ATR_MANA]   = 0;
    attribute[ATR_HITPOINTS_MAX]= 340;
    attribute[ATR_HITPOINTS]  = 340;

    protection[PROT_FIRE]  = 1000;

    Npc_SetTalentSkill (self, NPC_TALENT_PICKPOCKET,1);Npc_SetTalentValue(self,NPC_TALENT_PICKPOCKET,60); 
    Npc_SetTalentSkill (self, NPC_TALENT_SNEAK, 1); 
    Npc_SetTalentSkill (self, NPC_TALENT_PICKLOCK, 1);Npc_SetTalentValue(self,NPC_TALENT_PICKLOCK,60); 
    Npc_SetTalentSkill (self, NPC_TALENT_MAGE,  6);

    Npc_SetTalentSkill (self, NPC_TALENT_1H,1);
    Npc_SetTalentSkill (self, NPC_TALENT_BOW,1);

    //-------- inventory --------
    EquipItem   (self, Diegos_Bogen);
    EquipItem   (self, ItMw_1H_Sword_04);
    CreateInvItems  (self, ItAmArrow, 100);

    //-------- ai --------
    daily_routine     = Rtn_PreStart_1;
    fight_tactic     = FAI_HUMAN_MASTER;
    self.aivar[AIV_IMPORTANT] = TRUE;
    senses      = SENSE_SEE|SENSE_HEAR|SENSE_SMELL;
};

and here is the regex I'm using:

Regex ireg = new Regex("(instance|prototype)\\s+(?<ins>[^\\s]+).*\\{(?<text>[^(\\};)]+)\\};", RegexOptions.ExplicitCapture | RegexOptions.IgnoreCase | RegexOptions.Singleline);

However when I run this Rgex, I get the group, but all the group contains is 2 newlines. What am I doing wrong? I set the regex to singleline mode so that . would also match \n. Is that a wrong way of doing this? Can anyone help?

Thanks.

A: 

Not even sure what your regex is supposed to do, but this one should work:

"name\s*=\s*\"([^\"]*)\"\s*;"

The [^\"] part matches anything but a ". If the game script allows " inside names using some escaping mechanism, you'd have to modify the regex.

Here is a good place to test regular expressions.

Andomar
My regex is meant to capture 1. the INSTANCE name eg PC_Thief and 2. the whole text of the script, without the { and };Then that script is passed to another function which actually parses the script.
Radius
Also sorry, I just noticed that my > and < tags were eaten in the first post - the <ins> group captures correctly, but the <text> group only contains 2 newlines.
Radius
After testing a bit on the site you posted, i noticed that the regex has trouble matching the }; needed to end the script. Does the ; have to be escaped? Even if I try to just match the }, the regex matches nothing. How do I match the } properly?
Radius
Right, you wanted the name, I see Jass got it right already. The } is a special character, you can escape it like \}. It's used to specify the amount of repetition, f.e. a{1,3} would match between one and three a's.
Andomar
+1  A: 

I read your comments and i think this regex should do the trick

(instance|prototype)\\s+(?<ins>[^\\s(]+)[^{]*{(?<text>[^}]+)};

Note: I have already escaped characters as required for .net.

I recommend that you use the regex this way instead of using escape character for .net, this is much cleaner to read

@"(instance|prototype)\s+(?<ins>[^\s(]+)[^{]*{(?<text>[^}]+)};"

The capture group 'ins' will contain "PC_Thief" and 'text' will contain the entire input between { and }

Jass
Thanks. It works!
Radius