C# 在C语言中计算一个特殊表达式#
我有一个字符串,它有一个特殊格式的特殊子字符串: $(变量名称) 这种模式可以重复很多次: $(variableName$(另一个variableName)) 例如:[测试字符串] 下面是一个包含$(variableA)和 $(变量B$(变量C)) 对于这个测试字符串,假设 $(variableA)=A,$(variableB)=B,$(variableC)=C,$(variableBC)=Y 我想要的是用实际值替换那些特殊模式->$(variableName),例如 结果字符串应为: 下面是一个包含a和Y的测试字符串C# 在C语言中计算一个特殊表达式#,c#,parsing,string-parsing,C#,Parsing,String Parsing,我有一个字符串,它有一个特殊格式的特殊子字符串: $(变量名称) 这种模式可以重复很多次: $(variableName$(另一个variableName)) 例如:[测试字符串] 下面是一个包含$(variableA)和 $(变量B$(变量C)) 对于这个测试字符串,假设 $(variableA)=A,$(variableB)=B,$(variableC)=C,$(variableBC)=Y 我想要的是用实际值替换那些特殊模式->$(variableName),例如 结果字符串应为: 下面是一
对通用和优雅的解决方案有什么建议吗?这里是一个简单的解决方案,执行以下操作:
公共静态字符串替换(
字符串输入
,参考int pos
,i字典变量
,bool stopOnClose=false
) {
var res=新的StringBuilder();
while(位置!=输入长度){
开关(输入[pos]){
案例“\\”:
pos++;
如果(位置!=输入长度){
res.Append(输入[pos++]);
}
打破
案例“)”:
如果(停止关闭){
return res.ToString();
}
res.Append(');
pos++;
打破
案例“$”:
pos++;
如果(pos!=input.Length&&input[pos]=='('){
pos++;
变量名称=替换(输入,参考位置,变量,真);
字符串替换;
if(变量TryGetValue(名称,输出替换)){
附加(替换)决议;
}否则{
决议附件(“”);
}
pos++;
}否则{
res.Append(“$”);
}
打破
违约:
res.Append(输入[pos++]);
打破
}
}
return res.ToString();
}
公共静态void Main(){
const string input=“这里是一个测试字符串,包含$(variableA)和$(variableB$(variableC))”;
var vars=新字典{
{“variableA”、“A”}、{“variableB”、“B”}、{“variableC”、“C”}、{“variableBC”、“Y”}
};
int pos=0;
控制台写入线(替换(输入、参考位置、变量));
}
此解决方案重用Replace
的实现,通过将stopOnClose
标志设置为true
来调用自身,从而生成要替换的变量的名称。顶级调用不会在到达')
符号时停止,从而允许您在无需scaped的情况下使用它
因此,对于您的sintax$(variableB$(variableC))计算为$(variableBC)?您通常使用一个自定义解析器来完成这项工作,它既不是特别通用,也不是特别优雅。@MauricioGracia:是的,您可以通过多次调用
Replace
方法来完成。或者您可以编写一个简单的解析器。解析器通常会更快,而且构建起来也不太困难。但是你的里程可能会有所不同。@MauricioGracia语言非常简单的事实并不意味着它不能从解析器中获益。它通常意味着解析器也将非常简单;-)@JimMischel虽然你肯定对解析器不是泛型的说法是正确的,但他们的优雅是旁观者眼中的。那个ideone网站看起来不错,但你的示例实际上不允许任何输入进行测试it@MauricioGracia单击[clone]
,编辑Main
方法中的字符串,然后单击[Submit]
。你说得对:情人眼里出西施。我不觉得这个“优雅”,尽管我确实觉得它是解决这个问题的一个很好的方法。这就是为什么我把它投了更高的票。@DourHighArch谢谢,这个问题现在已经解决了!
public static string Replace(
string input
, ref int pos
, IDictionary<string,string> vars
, bool stopOnClose = false
) {
var res = new StringBuilder();
while (pos != input.Length) {
switch (input[pos]) {
case '\\':
pos++;
if (pos != input.Length) {
res.Append(input[pos++]);
}
break;
case ')':
if (stopOnClose) {
return res.ToString();
}
res.Append(')');
pos++;
break;
case '$':
pos++;
if (pos != input.Length && input[pos] == '(') {
pos++;
var name = Replace(input, ref pos, vars, true);
string replacement;
if (vars.TryGetValue(name, out replacement)) {
res.Append(replacement);
} else {
res.Append("<UNKNOWN:");
res.Append(name);
res.Append(">");
}
pos++;
} else {
res.Append('$');
}
break;
default:
res.Append(input[pos++]);
break;
}
}
return res.ToString();
}
public static void Main() {
const string input = "Here is a test string contain $(variableA) and $(variableB$(variableC))";
var vars = new Dictionary<string, string> {
{"variableA", "A"}, {"variableB", "B"}, {"variableC", "C"}, {"variableBC", "Y"}
};
int pos = 0;
Console.WriteLine(Replace(input, ref pos, vars));
}