Замена нескольких вхождений строки с помощью строителя строк путем сопоставления с регулярным выражением - PullRequest
3 голосов
/ 02 июля 2019

Мы пытаемся заменить все подходящие шаблоны (регулярные выражения) в построителе строк их соответствующими «группами».

Во-первых, мы пытаемся найти количество всех вхождений этого паттерна и пройти через них (условие окончания счета). Для каждого совпадения мы назначаем объект сопоставления и заменяем их, используя соответствующие группы.

Здесь заменяется только первое вхождение, а другие совпадения никогда не заменяются.

      *str* - contains the actual string

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

Для соответствия шаблону:

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

Шаблон: создан с использованием 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();
}

Токовый выход:

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

Ожидаемый результат:

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

1 Ответ

0 голосов
/ 02 июля 2019

Такое регулярное выражение слишком хрупкое.Если вам нужно проанализировать любой произвольный SQL, вам нужен выделенный анализатор.Существуют примеры того, как правильно анализировать SQL в Синтаксический анализ кода SQL в C # .

Если вы уверены, что в ваших входных данных нет «диких», несбалансированных ( и )Вы можете использовать регулярное выражение в качестве временного решения для одноразового задания:

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

См. демонстрационную версию regex .

Подробно

  • ('[^']+') - Группа захвата 1 ($1): ', 1 или более символов, отличных от ', а затем '
  • \s*=\s* -=, заключенный в 0+ пробелов
  • (\w+\((?>[^()]+|(?<o>\()|(?<-o>\)))*\)) - Группа захвата 2 ($2):
...