我正在建立一个简单的对话系统,并希望“动态化”某些句子。 例如,我有一个句子
嘿冒险家{{PlayerName}}! 欢迎世界各地!
现在在代码中,我试图用游戏中字符串的实际值替换它。我正在做这样的事情。但这是行不通的。我的功能所在的组件中确实有一个string PlayerName
Regex regex = new Regex("(?<={{)(.*?)(?=}})");
MatchCollection matches = regex.Matches(sentence);
for(int i = 0; i < matches.Count; i++)
{
Debug.Log(matches[i]);
sentence.Replace("{{"+matches[i]+"}}", this.GetType().GetField(matches[i].ToString()).GetValue(this) as string);
}
return sentence;
但是即使匹配正确,这也会返回一个错误。
有什么方法可以解决,还是做得更好?
答案 0 :(得分:1)
这是我要解决的方法。
创建一个字典,其中包含要替换的键和要替换的键的值。
new_dataset$SequenceNr[1:16] <- 1
new_dataset$SequenceNr[17:32] <- 2
new_dataset$SequenceNr[33:48] <- 3
new_dataset$SequenceNr[49:64] <- 4
然后检查字典中值的文本。 如果您确定所有键都以“ [[]”开头,并以“]”结尾,那么这将是快速简便的事情。
Dictionary<string, string> valuesToReplace;
valuesToReplace = new Dictionary<string, string>();
valuesToReplace.Add("[playerName]", "Max");
valuesToReplace.Add("[day]", "Thursday");
这也将更快地工作,因为它允许您在不降低代码速度的情况下添加任意数量的变量。
答案 1 :(得分:0)
使用Regex.Replace方法和一个MatchEvaluator委托(未经测试):
Dictionary<string, string> Replacements = new Dictionary<string, string>();
Regex DialogVariableRegex = new Regex("(?<={{)(.*?)(?=}})");
string Replace(string sentence) {
DialogVariableRegex.Replace(sentence, EvaluateMatch);
return sentence;
}
string EvaluateMatch(Match match) {
var matchedKey = match.Value;
if (Replacements.ContainsKey(matchedKey))
return Replacements[matchedKey];
else
return ">>MISSING KEY<<";
}
答案 2 :(得分:0)
这现在有点老了,但我想我会更新上面接受的代码。它不会工作,因为每次循环迭代时都会重置起始索引,因此设置 startOfVar = i
在它遇到结束字符时会完全重置。另外,如果有一个开放的括号 '[' 而没有结束的括号,则会出现问题。您也不能再在文本中使用这些括号。
还将分隔符设置为单个字符。它测试正常,但如果我将我的播放器名称设置为“Rob}ert”,则在执行替换时会出现问题。
这是我在 Unity 中测试过的代码的更新:
public string EvaluateVariables(string str)
{
Dictionary<string, string> varDict = GetVariableDictionary();
List<string> varReplacements = new List<string>();
string matchGuid = Guid.NewGuid().ToString();
bool matched = false;
int start = int.MaxValue;
for (int i = 0; i < str.Length; i++)
{
if (str[i] == '{')
{
if (str[i + 1] == '$')
{
start = i;
matched = true;
}
}
else if (str[i] == '}' && matched)
{
string replacement = str.Substring(start, (i - start) + 1);
if (varDict.ContainsKey(replacement))
{
varReplacements.Add(replacement + matchGuid + varDict[replacement]);
}
start = int.MaxValue;
matched = false;
}
}
foreach (string replacement in varReplacements)
{
str = str.Replace(replacement.Split(new string[] { matchGuid }, StringSplitOptions.None)[0], replacement.Split(new string[] { matchGuid }, StringSplitOptions.None)[1]);
}
return str;
}
private Dictionary<string, string> GetVariableDictionary()
{
Dictionary<string, string> varDict = new Dictionary<string, string>();
varDict.Add("{$playerName}", playerName);
varDict.Add("{$npcName}", npcName);
return varDict;
}