Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by IsaiahKelly · Jun 12, 2017 at 02:41 AM · conversionfile-ioparsestring formattingregularexpressions

Parsing a Custom Scripting Language

I'm creating a parser to import data into Unity from text files that use a custom scripting language created by someone else. I only need to import the data at editor time, so speed and performance is not a huge concern.

Now I can extract data from a single line easily using String.StartsWith() and String.Split(), but I'm not sure how best to do more complex multi-line arguments. Here's the data structure I'm trying to extract from.

 KEYWORD ID {    
     SCALE_XY    32, 32;
     CYCLES    6;
     BMAPS    wnoise1_map, wnoise2_map, wnoise3_map, wnoise4_map, wnoise5_map, wnoise6_map;
     DELAY    3,3,3,3,3,3;
 }

I want to find the line that starts with "KEYWORD" then parse the ID after the keyword and all values between the curly brackets. Excluding commas, semicolons, etc. Putting each argument in a string in an array.

Here's what I've come up with so far:

     StreamReader stream = File.OpenText(filename);
     string entireText = stream.ReadToEnd();
     stream.Close();

     using (StringReader reader = new StringReader(entireText))
     {
         string currentLine = reader.ReadLine();
         while (currentLine != null)
         {
             if (currentLine.StartsWith("KEYWORD"))
             {
                 string text = "";
                 // Read until closing curly bracket.
                 while (!currentLine.EndsWith("}"))
                 {
                     text += currentLine;
                     currentLine = reader.ReadLine();
                 }
                 // Split text up by semicolon.
                 string[] textArray = text.Split('{', ';');
             }
             currentLine = reader.ReadLine();
         }
     }

Anyone know of a better / easier / simpler way to do this? I've experimented with regular expressions, but that doesn't seem to be any easier to get working.

Comment
Add comment · Show 7
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image IsaiahKelly · Jun 12, 2017 at 02:47 AM 0
Share

At the moment I'm thinking maybe I should use String functions in combination with a state machine? First find the correct line with String.StartsWith() then use it again to check each line between the curly brackets after that for other keywords and so on, etc.

avatar image Dibbie · Jun 12, 2017 at 04:56 AM 0
Share

Yeah, I think the easiest way IS to use Split... Use StartsWith to get "$$anonymous$$EYWORD", then use Split to split it by either \n (new line) or ; (semi-colon), then youll end up with each of those 4 lines in its own string, you can then remove from \t (however many tabs you have between each word and the values), so youd then end up with a string array of JUST your values with your commas, but it shouldnt contain any semi-colons at this point

From there, you can decide how you wanna continue to split and handle your data for whatever you actually need to use it for, split by a comma to get specific values if needed, use Find to see if you have specific values, etc...

If you post the current code you are using to parse the file, I (or someone else) may be able to provide you with some example code to help you out as well.

avatar image IsaiahKelly Dibbie · Jun 12, 2017 at 07:56 PM 0
Share

So far I've been using StreamReader to load all the contents of the text file, and then StringReader.ReadLine() to go over each line.

 void ParseFile(string filename)
 {
     StreamReader stream = File.OpenText(filename);
     string entireText = stream.ReadToEnd();
     stream.Close();

     using (StringReader reader = new StringReader(entireText))
     {
         string currentLine = reader.ReadLine();

         while (currentLine != null)
         {
             // Parse current line.
             Parse$$anonymous$$eyword(currentLine);

             // Go to next line.
             currentLine = reader.ReadLine();
         }
     }
 }

 void Parse$$anonymous$$eyword(string text)
 {
     if (text.StartsWith("$$anonymous$$EYWORD"))
     {
         Debug.Log("$$anonymous$$eyword Found: " + text);
     }
 }

This of course doesn't work for multi-line arguments though. I've tried feeding the entire text into my parsing function, but then it doesn't return any results at all? Also, if I get this working I'm not sure what would stop it from returning everything in the entire file after the keyword? Would I then use String.EndsWith() or something to stop it?

avatar image Habitablaba IsaiahKelly · Jun 12, 2017 at 08:46 PM 0
Share

You could come up with a token to use to denote a multi line arguement. something like '/' that you could put at the end of a line to signal to your parser that you need to read the next line, too.

When you do you ReadLine call, you could check if the string ends with your token, and if so, call ReadLine again (obviously you'd want to continue to ReadLine while the string you just read in ends with your token).

Then you can concatenate all your strings into a single string and parse that.

avatar image jmgek · Jun 12, 2017 at 09:44 PM 0
Share

So you're going to want to work with generics here, and I have a good answer for you that does not involve string parsing, but I need to know why you're passing in your data like that.

avatar image IsaiahKelly jmgek · Jun 13, 2017 at 02:03 PM 0
Share

I realize now my earlier wording might have been a bit misleading. This "custom scripting language" was not created by me. The scripts were created for another program completely unrelated to Unity. I'm just trying to convert select parts of the data in these scripts to something I can use in my own C# classes in Unity. A total conversion of the data is not necessary or even possible. I just need to extract the relevant parts I need.

I should also note that performance is of little concern to me here because this is all being done in the editor and not at run time.

avatar image jmgek · Jun 13, 2017 at 05:28 PM 0
Share
  • realize now my earlier wording might have been a bit misleading. This "custom scripting language" was not created by me. The scripts were created for another program completely unrelated to Unity. I'm just trying to convert select parts of the data in these scripts to something I can use in my own C# classes in Unity. A total conversion of the data is not necessary or even possible. I just need to extract the relevant parts I need. I should also note that performance is of little concern to me here because this is all being done in the editor and not at run time.*

Awe, darn, I was hoping you could have at least put a delimiter in between your keys.

I was going to say take that key and put it in the in a dictionary, then use the values as a list in the dictionary. Then you could have invoked a function using the keys '$$anonymous$$EYWORD' with the values as passed arguments. https://stackoverflow.com/questions/4233536/c-sharp-store-functions-in-a-dictionary

I didn't realize you're only looking for '$$anonymous$$EYWORD' if you were checking, so I hate to say it the way you're currently doing it is the best way.

0 Replies

· Add your reply
  • Sort: 

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

67 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

iPhone System.IO.File.Exists() not working 1 Answer

[SOLVED] Bad PKCS7 While encrypting a file 1 Answer

Is accessing user documents folder possible on Unity3D? 0 Answers

CaptureScreenshot writing to Phone, but persistentdatapath linking to the external card. 0 Answers

Resources Load to open pdf is not working anymore in Android 7 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges