如何替换代码中的字符串

时间:2009-06-12 21:56:48

标签: replace

我想按照一些规则对项目执行批量替换操作。对于例如我在代码中记笔记如下:

在每个代码段上,这样注释,我想执行一个替换操作,它将输入代码段替换为以下示例中的输出代码段:

输入1:

//+
a++;
//+(+SomeException$SomeMessage)

输出1:

try
{
    a++;
}
catch (AnException)
{
    throw;
}
catch (Exception ex)
{
    throw new SomeException("SomeMessage", "15", ex);
}

输入2:

//+
a++;
//-(+InvalidOperationException$SomeMessage)

输出2:

try
{
    a++;
}
catch (InvalidOperationException ex)
{
    throw new AnException("SomeMessage", "16", ex);
}

输入3:

//+
a++;
//-(SomeMessage)

输出3:

try
{
    a++;
}
catch (Exception ex)
{
    throw new AnException("SomeMessage", "17", ex);
}

对于像这样评论的每个代码段,幻数(15,16,17)将增加。我知道这不是最好的做法,但我没有做出决定,我希望能处理这样的异常,所以我想我最终可以通过记笔记和批量替换来减轻痛苦。做这个的最好方式是什么?我应该编写自己的代码来执行替换,还是有一些正则表达式替换工具或类似的东西可以自动为我做这个?

更新:这是一次性工作,我的幻数必须是全球唯一的。因此,如果文件中的最后一场比赛为25,则下一个文件中的第一场比赛必须为26。

6 个答案:

答案 0 :(得分:1)

  

最好的方法是什么?我应该编写自己的代码来执行替换,还是有一些正则表达式替换工具或类似的东西可以自动为我做这个?

我会用C ++或C#编写一个小程序来执行此操作。可能有其他工具和脚本语言可以做到这一点;但鉴于它在C ++或C#中是一项微不足道的工作,并且我知道如何用这些语言来做,为什么不呢?

我不知道你的“最佳”方式是什么意思,但至少对我来说这将是最简单的方法之一。

答案 1 :(得分:0)

这看起来像一种简单的语言,你将要编译成另一种看起来像Java的语言。编译器是这样的工作的正确工具,特别是因为你需要保持当前幻数的状态。似乎做出决定的任何人都希望为语言添加新功能,在这种情况下,使用正则表达式粘合在一起的解决方案可能无法正常工作。

如果我对你真正想要的是对的,你的问题就会变成“如何编写领域特定语言?”的问题。我不确定最好的方法是什么,但是如果你知道Perl,你可以用Parse::RecDescent组合一个解决方案。

我认为这可能是通过脚本和正则表达式来实现的,但这是编译器发明的问题类型。如果你最终制造了一些hacky,那么上帝会帮助那些必须在你之后保持它的人! :)

答案 2 :(得分:0)

您可以编写一个CodeSmith模板来读取该输入并输出该输出。但是,我不确定你能否在线进行。也就是说,您需要一个只有输入的文件,然后您的模板可以为您提供输出文件。我不确定那是否可以接受。

答案 3 :(得分:0)

有很多方法可以做到这一点,即使你可能不应该(正如你似乎意识到的那样,这只会导致毫无意义的异常)。不过,这里有一个sed / sh组合来做第一个。它不处理自动编号或您的其他变体。我将把它作为OP的练习。

P1='\/\/+'; P2='\(.*\)'; P3='\/\/+(+\([^$]*\)$\(.*\))'; 
echo 'foo()\n//+\na++\n//+(+SomeException$Message)'|sed ' /'$P1'/ { N; /'$P2'/ { N; /'$P3'/ { s/'$P1'\n'$P2'\n'$P3'/try\n{\n\t\1\n}\ncatch (AnException)\n{\n\tthrow;\n}\ncatch (Exception ex)\n{\n\tthrow new \2("\3", "0", ex);\n}/ } } } '

回声只是一个测试字符串。

答案 4 :(得分:0)

作为Emacs用户,对于一次性工作,我通过定义键盘宏来做到这一点, 然后使用set / increment / insert-register进行自动编号魔术。那里 不应该真正需要编写自己的elisp函数。

虽然如果您需要在不仅仅是几个文件上执行此操作,您还可以 可能最好写一个脚本来完成这项工作。

答案 5 :(得分:0)

如果您没有使用像Emacs这样的IDE(由许多人回答)具有强大的正则表达式支持,我会编写一个小脚本。注意,文本操作通常更像是脚本操作,例如, Perl,Ruby,由于语言本身的正则表达式支持。另一方面,如果您非常熟悉Java Pattern,那么使用Java编写它可能是最快的解决方案,即使您需要更多的开销esp。一次性操作。

所以一个小小的Ruby脚本可能看起来像那样(小心,我没有测试它):

$cnt = 1
IO.readlines(filename).collect { |line|
  if line =~ /^\s*\/\/\+\s*$/
    $cnt += 1
    ["try\n", "{\n" ]
  elsif line =~ /^\s*\/\/\+\(\+(.+)\$(.+)\)\s*/
    ["}\n", "catch (#{$1} ex)\n", "{\n", 
       "throw new AnException(\"#{$2}\", \"#{$cnt}\", ex);\n", "}\n"]
  # propably more else for all cases
  else
    line
  end
}.flatten
# save the file again