C#学习教程:我可以在运行时扩展包含C#文字表达式的字符串分享


我可以在运行时扩展包含C#文字表达式的字符串

如果我有一个包含ac#string文字表达式的字符串,我可以在运行时“展开”它

public void TestEvaluateString() { string Dummy = EvalString( @"Contains rn new line"); Debug.Assert(Dummy == "Contains rn new line"); } private string EvalString(string input) { return "Contains rn new line"; } 

就像我可以将C#字符串值转换为转义字符串文字 ,但反过来?

类似于Mikael的答案,但使用CSharpCodeProvider:

  public static string ParseString(string txt) { var provider = new Microsoft.CSharp.CSharpCodeProvider(); var prms = new System.CodeDom.Compiler.CompilerParameters(); prms.GenerateExecutable = false; prms.GenerateInMemory = true; var results = provider.CompileAssemblyFromSource(prms, @" namespace tmp { public class tmpClass { public static string GetValue() { return " + """ + txt + """ + @"; } } }"); System.Reflection.Assembly ass = results.CompiledAssembly; var method = ass.GetType("tmp.tmpClass").GetMethod("GetValue"); return method.Invoke(null, null) as string; } 

你可能最好使用通配符字典,只需在字符串中替换它们。

不确定这是否是最简单的方法,但通过引用Microsoft.JScript命名空间,您可以使用javascript eval函数重新解析它。

这是对底部代码的测试

 var evalToString = Evaluator.MyStr("test \r\n test"); 

这会将 r变为回车符。

并实施

 public class Evaluator { public static object MyStr(string statement) { return _evaluatorType.InvokeMember( "MyStr", BindingFlags.InvokeMethod, null, _evaluator, new object[] { statement } ); } static Evaluator() { ICodeCompiler compiler; compiler = new JScriptCodeProvider().CreateCompiler(); CompilerParameters parameters; parameters = new CompilerParameters(); parameters.GenerateInMemory = true; CompilerResults results; results = compiler.CompileAssemblyFromSource(parameters, _jscriptSource); Assembly assembly = results.CompiledAssembly; _evaluatorType = assembly.GetType("Evaluator.Evaluator"); _evaluator = Activator.CreateInstance(_evaluatorType); } private static object _evaluator = null; private static Type _evaluatorType = null; private static readonly string _jscriptSource = @"package Evaluator { class Evaluator { public function MyStr(expr : String) : String { var x; eval(""x='""+expr+""';""); return x; } } }"; } 

如果您只是想在Microsoft站点上定义“简单”转义字符,则可以使用此例程并保存导入外部库:

 public static class StringExtensions { /* https://msdn.microsoft.com/en-us/library/aa691087(v=vs.71).aspx */ private readonly static SortedDictionary EscapeMap = new SortedDictionary { { ''', ''' }, { '"', '"' }, { '\', '\' }, { '0', '' }, { 'a', 'a' }, { 'b', 'b' }, { 'f', 'f' }, { 'n', 'n' }, { 'r', 'r' }, { 't', 't' }, { 'v', 'v' }, }; public static string UnescapeSimple(this string escaped) { if (escaped == null) return escaped; var sb = new StringBuilder(); bool inEscape = false; var s = 0; for (var i = 0; i < escaped.Length; i++) { if (!inEscape && escaped[i] == '\') { inEscape = true; continue; } if (inEscape) { char mapChar; if (EscapeMap.TryGetValue(escaped[i], out mapChar)) { sb.Append(escaped.Substring(s, i - s - 1)); sb.Append(mapChar); s = i + 1; } inEscape = false; } } sb.Append(escaped.Substring(s)); return sb.ToString(); } } 

这是一个unit testing来certificate它:

  [TestMethod] public void UnescapeSimpleTest() { var noEscapes = @"This is a test".UnescapeSimple(); Assert.AreEqual("This is a test", noEscapes, nameof(noEscapes)); var singleEscape = @"n".UnescapeSimple(); Assert.AreEqual("n", singleEscape, nameof(singleEscape)); var allEscape = @"'""\abfnrtv".UnescapeSimple(); Assert.AreEqual("'"\abfnrtv", allEscape, nameof(allEscape)); var textInEscapes = @"tthisnris\antest".UnescapeSimple(); Assert.AreEqual("tthisnris\antest", textInEscapes, nameof(textInEscapes)); var backslashNoEscapes = @",hqtest".UnescapeSimple(); Assert.AreEqual(@",hqtest", backslashNoEscapes, nameof(backslashNoEscapes)); var emptyStr = "".UnescapeSimple(); Assert.AreEqual("", emptyStr, nameof(emptyStr)); // Prove Enviroment.NewLine is "rn" and not "nr" (Windows PC) var newLine = @"rn".UnescapeSimple(); Assert.AreEqual(Environment.NewLine, newLine, nameof(newLine)); // Double check prior test (Windows PC) var newLineWrong = @"nr".UnescapeSimple(); Assert.AreNotEqual(Environment.NewLine, newLineWrong, nameof(newLineWrong)); } 

随意调整EscapeMap或重命名函数UnescapeSimple(我知道这很尴尬)。

请注意,此解决方案不处理Unicode转义字符或hex或八进制,它只处理简单的单字符。

Regex.Unescape将是我的首选方法。

上述就是C#学习教程:我可以在运行时扩展包含C#文字表达式的字符串分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注---猴子技术宅(www.ssfiction.com)

本文来自网络收集,不代表猴子技术宅立场,如涉及侵权请点击右边联系管理员删除。

如若转载,请注明出处:https://www.ssfiction.com/ckf/959854.html

发表评论

邮箱地址不会被公开。 必填项已用*标注