2009-06-12 62 views
1

我想按照一些规则对项目执行批量替换操作。对于例如我在这样的代码中记录:如何在代码中替换字符串

对于每个代码片段,我都要执行替换操作,它将用以下示例中的输出代码片段替换输入代码片段:

输入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。

回答

0

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

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

我认为这可能是通过脚本和正则表达式来实现的,但这是编译器发明的问题类型。如果你最终做出一件怪事,上帝会帮助那些在你身后维护它的人! :)

+0

不幸的是,我不知道Perl和我不是想写一个DSL。我只想替换我的代码中的一些字符串,并增加每场比赛的魔术数字。 – 2009-06-12 22:25:26

+0

我认为你正在尝试实现你的源代码的评论中存在的DSL。这听起来像是为你写的。 :) 像这样的实现操作不仅仅是一个简单的搜索和替换问题,您需要解析输入并根据输入被解析的方式发出符号。这是编译器的工作,你可能需要编写或使用它。 – 2009-06-12 22:49:00

0

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

+0

我看了代码史密斯教程,我想我可以使用实际的.cs文件作为模板。我希望它能将一个状态从一个模板文件转移到另一个状态,因为这个幻数必须是全局唯一的。 – 2009-06-12 22:30:19

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}/ } } } ' 

echo只是一个测试字符串。

+0

非常感谢大量的正则表达式写入时间,但是一旦我找出正确的工具或方法,我想我可以自己组成正则表达式。这里最大的问题是自动编号。 – 2009-06-12 22:53:40

1

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

我会用C++或C#编写一个小程序来做到这一点。据推测,其他工具和脚本语言可以做到这一点;但考虑到在C++或C#中这是一项微不足道的工作,并且我已经知道如何在这些语言中完成它,为什么不呢?

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

0

作为一名Emacs用户,对于一次性工作,我会通过定义键盘宏 来完成此操作,然后使用set/increment/insert-register作为自动编号魔术。 应该不需要编写自己的elisp函数。

虽然如果您需要在不止一两个文件上执行此操作,您可能会更好地编写脚本来完成这项工作。

0

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

所以豆蔻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