4

我想做的是以编程方式插入一行代码(C#,意思是打开一个现有文件并写入它)(见下文):

我有MyClass.cs

public class MyClass
{
  public void HelloWorld()
  {
    //hello world
    switch(somevalue)
    {
      case derp:
      //do something here
      break;
    }
    <--------INSERT CODE HERE -------->
  }
}

这样做的最佳方法是什么?如何找到方法“HelloWorld”,然后找到“匹配的”右括号 ( } )?

许多人可能想知道为什么我想要这个(因为它看起来有点愚蠢)。我想要这个,因为我在为 Windows 应用商店应用程序构建时正在为 Unity 编写 PostProcess 脚本。并且在每次新构建之后都需要手动添加一些东西(我想自动添加它以尽量减少可能出错/被遗忘的东西的数量)。

编辑

显然我不够清楚。上面的代码只是一个例子的意思,它不会和上面的代码例子完全一样。可能有也可能没有开关盒。可能有额外{的 和}字符(尽管总会有一个匹配的开始和结束括号)。没有“占位符”,这意味着没有“ <--------INSERT CODE HERE --------> ”我可以找到并替换。如果事情这么简单,我就不会寻求帮助了!抱歉,如果我不清楚,但老实说,我认为我提供了足够的信息。

4

4 回答 4

2

给定一些限制:

  1. 该类不包含带有开/关大括号的字符串文字。
  2. 您需要插入行的方法始终位于大括号嵌套的第二级。
  3. 您需要将该行插入所有此类方法。
  4. 也许还有其他一些限制?

你可以像我刚刚用 JavaScript 写的那样写一个简单的程序:

var str = '{test{test2{test3}{test4}}{test5}}';

var stack = [];

var result = '';
for (var i = 0, len = str.length; i < len; i++) {
    var chr = str[i];
    var resChr = chr;
    if(chr == '{') {
        stack.push(chr);
    }
    if (chr == '}') {
        stack.pop();

        if (stack.length == 1) {
            resChr = 'your line;' + chr;
        }
    }

    result += resChr;
}

console.log(result);

JsFiddle https://jsfiddle.net/dus2jj63/

结果将是

{test{test2{test3}{test4}your line;}{test5your line;}}

代码可能看起来很难看,你可以在这里做很多优化。如果您需要找到具有特定名称的方法,还可以添加简单的调整。

PS首先尝试用正则表达式解决它,但结果并不那么容易。

PSS 另一个带有您提供的示例的 JsFiddle https://jsfiddle.net/xhezcg7a/

于 2015-05-07T20:59:57.997 回答
1

尝试这个:

//this should return what you want
Regex.Replace(
       fileContents, 
       //after the first closing brace found in HelloWorld(). Tweak to taste.
       @"(?<=          (?# text is preceded by...)
        HelloWorld()   (?# the HelloWorld function)
        [^}]*})        (?# code up to the first closing brace)
        \s*?           (?# the first whitespace after the first closing brace)"
       Environment.Newline + newCode, 
       RegexOptions.Singleline | RegexOptions.IgnorePatternWhitespace);

请注意,它基本上是一行代码。我的座右铭是“简单就是更好”和“更少的代码意味着更少的维护”。

于 2015-05-07T18:24:16.360 回答
0

您在这里确实没有提供足够的信息来获得可靠的答案。

最简单的方法是使用您要插入的任何内容string.Replace替换您的“<--------在此处插入代码-------->”文本。

但尚不清楚该文本是否真的出现在您正在修改的文件中。

最后,如果您确实需要在没有任何已知标记的情况下找到方法的结尾,那么您将需要一个更复杂的解析器来识别该方法及其结束的位置。这是可行的,但这是一项重大任务,并且远远超出了 stackoverflow 答案的范围。

于 2015-05-07T18:31:38.560 回答
0

我设法拼凑出一个“有效”的解决方案。它有一些 medvedev1088 提到的缺陷。它可能可以优化等等。我使用下面的代码来查找lineNumber. 当{找到的数量与找到的数量匹配}时,应该已经找到方法的结尾,假设在某些文本上下文中没有使用“}”。

然后我用StreamWriter写所有相同的行。当涉及到 时lineNumber,它会写入the-code-i-wanna-insert右括号 ( })。

private static int FindEndOfMethod(string filename, string methodToFind)
{
    int countStartBracket = 0;
    int countEndBracket = 0;

    string line = "";
    int lineNumber = -1;

    bool foundEnd = false;
    bool foundMethod = false;

    System.Action countBrackets = () =>
    {
        if (line.Contains("{"))
            countStartBracket++;
        if (line.Contains("}"))
            countEndBracket++;

        //If we found the method and the start and end bracke- count is the same we found the end (and they are not zero)
        if (foundMethod && countStartBracket == countEndBracket && countStartBracket != 0 && countEndBracket != 0)
            foundEnd = true;
    };


    //Pass the file path and file name to the StreamReader constructor
    using (StreamReader sr = new StreamReader(filename))
    {
        //Continue to read until you reach end of file
        while (line != null)
        {
            lineNumber++;

            //Read next line, if it's null, we reached end of file and didn't find the place
            if ((line = sr.ReadLine()) == null)
                return -1;

            //If we haven't found the method yet, we check each line to see if it's on this line
            if (!foundMethod)
                if (line.Contains(methodToFind))
                    foundMethod = true;

            //If it was or has been found we count brackets to determine the closing one
            if (foundMethod)
                countBrackets();

            if (foundEnd)
            {
                Debug.Log(lineNumber);
                return lineNumber;
            }
        }
        return -1;
    }
}
于 2015-05-07T21:17:39.980 回答