- Home /
Replace with a value from hashtable
Is it possible to do replace with a value from a hashtable when using Regex replace, depending on the string that Regex finds? I don't really know how to explain it good, so here's my code: string data_location; static Hashtable main;
void Start ()
{
// Start with importing language files
main = new Hashtable ();
data_location = Application.dataPath + "/data/language/EN/";
StreamReader main_file = new StreamReader (data_location + "main.txt");
string main_language = main_file.ReadToEnd ();
string[] main_language_lines = main_language.Split ('\n');
foreach (string line in main_language_lines)
{
// Save every line
if (line != "")
{
// Add the strings to the hashtable after processing them
string pattern = "{([A-z0-9_]+)}";
string[] line_content = line.Split ('|');
main.Add (line_content[0], Regex.Replace (line_content[1].Replace ("\\n", "\n"), pattern, (string) main["$1"]));
}
}
}
And here's the content of the file being imported:
GAME_NAME|Derpflerpia
VERSION|{GAME_NAME} PreAlpha v0.1
WELCOME|Welcome to {GAME_NAME}!
WELCOME_TEXT|{GAME_NAME} is still a WIP. Expect many derps and stoff.\n\nControls:\nW - Move forward\nA - Move left\nS - Move backwards\nD - Move right\nQ - Show current quests\nE - Teleport to the cave\nI - Open inventory\nP - Pause\nEsc - Close game\nEnter - Close this window
BACKPACK|Backpack
PAUSED|Paused
QUESTS|Quests
The problem lies in this line: main.Add (line_content[0], Regex.Replace (line_content[1].Replace ("\\n", "\n"), pattern, (string) main["$1"]));
If I replace it to this it works: main.Add (line_content[0], Regex.Replace (line_content[1].Replace ("\\n", "\n"), pattern, (string) main["GAME_NAME"]));
But then it will not work in future cases with other strings, so any suggestions how I should do?
Sorry about bad explanations
Answer by ArkaneX · Sep 28, 2013 at 08:01 PM
I'll start from different problem: you create StreamReader
without closing or disposing it. You should either call Close
/Dispose
, or just use using
keyword to automatically handle disposing
using(StreamReader sr = new StreamReader(path))
{
// read the data
}
You can use File.ReadAllLines as well, which has an advantage over StreamReader.ReadToEnd
, because it returns array of lines.
As to your question: it doesn't work, because substitution ($1 here) must be passed directly to the Replace
method. When you do main["$1"]
, substitution is not used, and you're just trying to get a value with key "$1" from hashtable. I suggest the following solution:
Dictionary<string, string> main = new Dictionary<string, string>(); // I suggest using Dictionary, because it is strongly typed and doesn't require any casting to string, like you did in your code
string pattern = @"\{([A-z0-9_]+)\}"; // this should be outside of foreach loop
foreach (var line in main_language_lines)
{
string[] line_content = line.Split('|');
string key = line_content[0];
string value = line_content[1].Replace("\\n", "\n");
var match = Regex.Match(value, pattern);
if (match.Success)
{
value = Regex.Replace(value, pattern, main[match.Groups[1].Value]);
}
main.Add(key, value);
}
Please note, that this is solution for single replacement. If you had the following line:
{GAME_NAME}, version {VERSION}
then you need to modify the sample code.