巧妙地替换字符串
Replace string smartly
我正在尝试将变量替换为文本字符串中的值,这是一个数学表达式。
math_Expresion = d + dft-t
到当前值:
1 + 32 - 4
然后用一个DataTable()计算出来
var result = new DataTable().Compute(math_Expresion, null);
但如果名称中的变量包含另一个变量则不起作用,例如
a = 1
aa = 22
d = a + aa
d.Replace ("a", a)
d.Replace ("aa", aa)
return 1 + 11 not 1 + 22
混淆了名字。
有没有一种方法可以用它们的值替换名称而不跳过它们、一些 ReplaceExacly()
函数或类似的东西来避免这种不适?
实际代码:
for (int i = 0; i < variables_cache.Count; i++)
{
if (math_expresion.Contains(variables_cache[i].name))
{
math_expresion = math_expresion.Replace(variables_cache[i].name, variables_cache[i].value);
}
}
var result = new DataTable().Compute(math_expresion, null);
您不必对公式做任何事情,您可以将变量作为 DataColumn
s:
private static object Compute(string formula,
IDictionary<string, object> variables = null) {
// using - don't forget to Dispose table which is IDisposable
using (DataTable table = new DataTable()) {
// If we have variables...
if (variables != null)
foreach (var pair in variables) // ... we create columns
table.Columns.Add(pair.Key, pair.Value.GetType()).DefaultValue = pair.Value;
// last column is computation result
table.Columns.Add().Expression = formula;
// result is the value of the last (computed) column
return table.Rows.Add()[table.Columns.Count - 1];
}
}
用法:
var variables = new Dictionary<string, object> {
{ "d", 1},
{ "dft", 32},
{ "t", 4},
};
var result = Compute("d + dft-t", variables);
Console.Write(result);
结果:
29
如果你坚持字符串处理你可以试试正则表达式来巧妙地替换:
using System.Text.RegularExpressions;
...
var variables = new Dictionary<string, object> {
{ "d", 1},
{ "dft", 32},
{ "t", 4},
};
var formula = "d + dft-t";
formula = Regex.Replace(
formula,
@"\b\p{L}[\p{L}\d_]*\b",
m => variables.TryGetValue(m.Value, out var value)
? value?.ToString()
: m.Value);
Console.Write(formula);
结果:
1 + 32-4
模式解释:
\b - word border
\p{L} - letter (unicode one, we can use, say, cyrillic letters as well)
[\p{L}\d_]* - zero or more letters, digits, or _
\b - word border
编辑: 要从 variables_cache
获取字典,您可以使用 Linq:
IDictionary<string, object> dict = variables_cache
.ToDictionary(item => item.name, (object) (item.value));
从技术上讲,您不需要字典,可以轻松使用自己的结构:
// Assuming that MyVariable has Name and Value properties or fields
private static object Compute(string formula,
IEnumerable<MyVariable> variables = null) {
// using - don't forget to Dispose table which is IDisposable
using (DataTable table = new DataTable()) {
// If we have variables...
if (variables != null)
foreach (var pair in variables) // ... we create columns
table.Columns.Add(pair.Name, pair.Value.GetType()).DefaultValue = pair.Value;
// last column is computation result
table.Columns.Add().Expression = formula;
// result is the value of the last (computed) column
return table.Rows.Add()[table.Columns.Count - 1];
}
}
我正在尝试将变量替换为文本字符串中的值,这是一个数学表达式。
math_Expresion = d + dft-t
到当前值:
1 + 32 - 4
然后用一个DataTable()计算出来
var result = new DataTable().Compute(math_Expresion, null);
但如果名称中的变量包含另一个变量则不起作用,例如
a = 1
aa = 22
d = a + aa
d.Replace ("a", a)
d.Replace ("aa", aa)
return 1 + 11 not 1 + 22
混淆了名字。
有没有一种方法可以用它们的值替换名称而不跳过它们、一些 ReplaceExacly()
函数或类似的东西来避免这种不适?
实际代码:
for (int i = 0; i < variables_cache.Count; i++)
{
if (math_expresion.Contains(variables_cache[i].name))
{
math_expresion = math_expresion.Replace(variables_cache[i].name, variables_cache[i].value);
}
}
var result = new DataTable().Compute(math_expresion, null);
您不必对公式做任何事情,您可以将变量作为 DataColumn
s:
private static object Compute(string formula,
IDictionary<string, object> variables = null) {
// using - don't forget to Dispose table which is IDisposable
using (DataTable table = new DataTable()) {
// If we have variables...
if (variables != null)
foreach (var pair in variables) // ... we create columns
table.Columns.Add(pair.Key, pair.Value.GetType()).DefaultValue = pair.Value;
// last column is computation result
table.Columns.Add().Expression = formula;
// result is the value of the last (computed) column
return table.Rows.Add()[table.Columns.Count - 1];
}
}
用法:
var variables = new Dictionary<string, object> {
{ "d", 1},
{ "dft", 32},
{ "t", 4},
};
var result = Compute("d + dft-t", variables);
Console.Write(result);
结果:
29
如果你坚持字符串处理你可以试试正则表达式来巧妙地替换:
using System.Text.RegularExpressions;
...
var variables = new Dictionary<string, object> {
{ "d", 1},
{ "dft", 32},
{ "t", 4},
};
var formula = "d + dft-t";
formula = Regex.Replace(
formula,
@"\b\p{L}[\p{L}\d_]*\b",
m => variables.TryGetValue(m.Value, out var value)
? value?.ToString()
: m.Value);
Console.Write(formula);
结果:
1 + 32-4
模式解释:
\b - word border
\p{L} - letter (unicode one, we can use, say, cyrillic letters as well)
[\p{L}\d_]* - zero or more letters, digits, or _
\b - word border
编辑: 要从 variables_cache
获取字典,您可以使用 Linq:
IDictionary<string, object> dict = variables_cache
.ToDictionary(item => item.name, (object) (item.value));
从技术上讲,您不需要字典,可以轻松使用自己的结构:
// Assuming that MyVariable has Name and Value properties or fields
private static object Compute(string formula,
IEnumerable<MyVariable> variables = null) {
// using - don't forget to Dispose table which is IDisposable
using (DataTable table = new DataTable()) {
// If we have variables...
if (variables != null)
foreach (var pair in variables) // ... we create columns
table.Columns.Add(pair.Name, pair.Value.GetType()).DefaultValue = pair.Value;
// last column is computation result
table.Columns.Add().Expression = formula;
// result is the value of the last (computed) column
return table.Rows.Add()[table.Columns.Count - 1];
}
}