简体   繁体   中英

Replacing mutiple occurrences of string using string builder by regex pattern matching

We are trying to replace all matching patterns (regex) in a string builder with their respective "groups".

Firstly, we are trying to find the count of all occurrences of that pattern and loop through them (count - termination condition). For each match we are assigning the match object and replace them using their respective groups.

Here only the first occurrence is replaced and the other matches are never replaced.

      *str* - contains the actual string

      Regex - ('.*')\s*=\s*(.*)

To match pattern:

    'nam_cd'=isnull(rtrim(x.nam_cd),''), 
    'Company'=isnull(rtrim(a.co_name),'')

Pattern : created using https://regex101.com/

*matches.Count* - gives the correct count (here 2)


String pattern = @"('.*')\s*=\s*(.*)";
MatchCollection matches = Regex.Matches(str, pattern);
StringBuilder sb = new StringBuilder(str);
Match match = Regex.Match(str, pattern);

for (int i = 0; i < matches.Count; i++)
{
    String First = String.Empty;
    Console.WriteLine(match.Groups[0].Value);
    Console.WriteLine(match.Groups[1].Value);

    First = match.Groups[2].Value.TrimEnd('\r');
    First = First.Trim();
    First = First.TrimEnd(',');

    Console.WriteLine(First);

    sb.Replace(match.Groups[0].Value, First + " as " + match.Groups[1].Value) + " ,", match.Index, match.Groups[0].Value.Length);
    match = match.NextMatch();
}

Current output:

SELECT DISTINCT
         isnull(rtrim(f.fleet),'') as 'Fleet' ,
        'cust_clnt_id' = isnull(rtrim(x.cust_clnt_id),'')

Expected output:

SELECT DISTINCT
 isnull(rtrim(f.fleet),'') as 'Fleet' ,
 isnull(rtrim(x.cust_clnt_id),'') as 'cust_clnt_id'

A regex solution like this is too fragile. If you need to parse any arbitrary SQL, you need a dedicated parser. There are examples on how to parse SQL properly in Parsing SQL code in C# .

If you are sure there are no "wild", unbalaned ( and ) in your input, you may use a regex as a workaround, for a one-off job:

var result = Regex.Replace(s, @"('[^']+')\s*=\s*(\w+\((?>[^()]+|(?<o>\()|(?<-o>\)))*\))", "\n $2 as $1");

See the regex demo .

Details

  • ('[^']+') - Capturing group 1 ( $1 ): ' , 1 or more chars other than ' and then '
  • \\s*=\\s* - = enclosed with 0+ whitespaces
  • (\\w+\\((?>[^()]+|(?<o>\\()|(?<-o>\\)))*\\)) - Capturing group 2 ( $2 ):
    • \\w+ - 1+ word chars
    • \\((?>[^()]+|(?<o>\\()|(?<-o>\\)))*\\) - a (...) substring with any amount of balanced (...) s inside (see my explanation of this pattern ).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM