簡體   English   中英

正則表達式替換重復捕獲

[英]Regex Replace repeated captures

我正在創建一個log4net appender,它可以生成准備執行的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+\)\],? ?)+)

它完美地匹配和捕獲我的樣本:

Expresso匹配輸出

我希望整個替代品由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);
    }

這很有效,但我確信這樣做更干凈利落。 也許使用不同的正則表達式?

任何幫助,將不勝感激。

這是一個更緊湊的正則表達式方法:

搜索: = (@p\\d+)(?=.*?\\1 (= [^\\[]+))|;(?!.*= @p\\d).*

替換: ${2}

這將所有參數替換為其值並擦除字符串的結尾。

請參閱正則表達式演示底部的“替換”窗格。

輸出:

command 5:UPDATE [PlanParameter] SET Mode = 1 , DefaultValueString = '0' , ParameterID = 2 WHERE ID = 1362 

樣本C#

String replaced = Regex.Replace(yourString, @"= (@p\d+)(?=.*?\1 (= [^\[]+))|;(?!.*= @p\d).*", "${2}");

說明

  • (@p\\d+)的括號將@p和數字捕獲到組1
  • 前瞻(?=.*?\\1 (= [^\\[]+))斷言以下是......
  • .*? 匹配任何字符...
  • \\1匹配組1(例如@p0
  • (= [^\\[]+))的括號將第二個字符串捕獲到文本= ,所有字符都不是[ (我們用它作為分隔符來知道你的值何時結束。這是你的價值
  • 或者...... | 我們也將匹配字符串的結尾,並且因為匹配時沒有第2組,所以替換${2}將使其無效
  • ; 分號
  • 為安全起見,負前瞻(?!.*= @p\\d)斷言(?!.*= @p\\d)內容不是任何字符= @p + digit
  • .*匹配一個分號和所有字符到字符串的末尾
  • 替換字符串${2}=和組2(值)

參考

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM