【发布时间】:2014-08-30 11:24:40
【问题描述】:
我正在创建一个 log4net 附加程序,它生成准备执行的 NHibernate SQL 脚本。
我想使用 Regex 将 log4net 的输出替换为准备使用的脚本。
样本输入将是
command 5:UPDATE [PlanParameter] SET Mode = @p0, DefaultValueString = @p1, ParameterID = @p2 WHERE ID = @p3;@p0 = 1 [Type: Int16 (0)], @p1 = '0' [Type: String (4000)], @p2 = 2 [Type: Int32 (0)], @p3 = 1362 [Type: Int32 (0)]
我想替换的
UPDATE [PlanParameter] SET Mode = 1, DefaultValueString = '0', ParameterID = 2 WHERE ID = 1362
我创建了以下正则表达式:
command \d+:(?<Query>(?:(?<PreText>[\w\s\[\]]+ = )(@p\d+)(?<PostText>,?))+);(?<Parameters>(?:@p\d+ = ('?\w+'?) \[Type: \w+ \(\d+\)\],? ?)+)
完美匹配并捕获我的样本:
我希望整个替换都由 Regex 引擎处理。我想我可以使用这样的替换字符串:
${PreText}$2${PostText}
但这只会产生最后一次捕获,而不是我的最终目标。
与此同时,我使用 C# 来实现它:
Regex reg = new Regex(@"command \d+:(?<Query>(?:(?<PreText>[\w\s\[\]]+ = )(@p\d+)(?<PostText>,?))+);(?<Parameters>(?:@p\d+ = ('?\w+'?) \[Type: \w+ \(\d+\)\],? ?)+)", RegexOptions.Compiled);
string sample = @"command 5:UPDATE [PlanParameter] SET Mode = @p0, DefaultValueString = @p1, ParameterID = @p2 WHERE ID = @p3;@p0 = 1 [Type: Int16 (0)], @p1 = '0' [Type: String (4000)], @p2 = 2 [Type: Int32 (0)], @p3 = 1362 [Type: Int32 (0)]";
Match match = reg.Match(sample);
string result = match.Groups["Query"].Value;
for (int i = 0; i < match.Groups[1].Captures.Count; i++)
{
Capture capture = match.Groups[1].Captures[i];
result = result.Replace(capture.Value, match.Groups[2].Captures[i].Value);
}
这非常有效,但我确信有一种更干净整洁的方法可以做到这一点。也许使用不同的正则表达式?
任何帮助将不胜感激。
【问题讨论】:
-
+1 用于试验 CaptureCollection :)
标签: c# sql regex nhibernate log4net