使用模板在运行时生成文本文件

时间:2017-03-10 10:11:10

标签: c# .net

我使用的是.NET Core 1.1,需要在运行时创建一个文本文件。例如:

import MyLib

a = 5
MyLib.doSomeStuff(a)

我唯一需要做的就是创建一个文本文件,但是在我的C#代码中通过一些计算给出了a的值。理想情况下,我希望在我的C#代码中有类似的东西:

// Variable to pass to be set on the script
int a = 5;
// Create the Python script and save to some .py file
CreatePythonScript(a);

请注意,这是一个最小的例子。在实践中,我的脚本有数百行和数百个变量,因此通过连续调用Write()手动编写文本文件不会那么聪明。

我检查了T4框架,但我认为这不是我需要的。我可以用它做什么?

1 个答案:

答案 0 :(得分:2)

您可以编写一个示例文件,其中包含一些明确定义的占位符,从那时起,它只是替换所有操作。

例如:

import MyLib

a = `a`
MyLib.doSomeStuff(a)

所以,你要做的是找出如何插入占位符,以便它产生在文本中找不到的字符串,因此你不能替换任何不应该的东西。更换。在这个例子中,(我根本不知道Python)假设反引号(`)通常不会出现,你可以使用它们来加前缀,后缀,或者将部分完全包装到应该插入动态值的部分。您还必须考虑特殊部分,否则它们可能出现在极端情况下:注释,字符串文字等。

要注意的另一件事是你的逻辑应该优先考虑占位符,这样如果有一个占位符是另一个的前缀,那么你必须先替换较长的占位符,否则通过替换较短的一个,您可以使较长的一个无效。请注意,如果您没有前缀或后缀,但换行包含通常无法显示的字符的部分,那么一个占位符永远不会是另一个占位符的前缀/后缀。

有了这些说法,我只建议选择一种简单明了的方法,因为如果模板很简单,那么你应该找一个专用的工具。

一个例子:

Dictionary<string, string> keysAndReplacements = new Dictionary<string, string>();

// Initialize the dictionary here.

// Custom logic to perform key prioritization. More on it below.
IEnumerable<string> prioritizedKeys = PrioritizeKeys(keysAndReplacements.Keys);

using (StreamReader reader = new StreamReader(@"C:\sample.txt"))
{
    string allText = reader.ReadToEnd();
    foreach (string key in prioritizedKeys)
    {
        allText = allText.Replace(key, keysAndReplacements[key]);
    }
}

此逻辑只读取整个模板,并用值替换占位符。字典的键是占位符(前缀后缀前缀+后缀)。

详细介绍&#39;以下&#39;:

  • 正如我所说,如果占位符有前缀和后缀,那么(假设前缀和后缀字符不会出现),就不可能发生冲突。
  • 最直接的实现是按密钥长度递减排序,因为那时你首先从较长的密钥开始,因此如果占位符是精确的,那么冲突只会发生(好吧,即使是碰撞)相同。由于词典不允许重复键,如果您尝试两次添加相同的键,则会遇到麻烦。
  • 为了安全起见,请不要在开头和结尾使用1-1个字符。使用几个包装器,这样可以减少字符串发生在您实际上不希望被替换的地方。例如:§§§a§§§。您使用的字符越不常见,就越不可能更换您不想要的内容,例如,在评论中。