Как заменить все данные символы? - PullRequest
2 голосов
/ 10 января 2020

Я пытаюсь написать метод, который заменяет все вхождения символов во входном массиве (charsToReplace) на replacementCharacter с использованием регулярных выражений. Версия, которую я написал , не работает , если массив содержит символы, которые могут изменить значение шаблона регулярного выражения, например ']' или '^'.

public static string ReplaceAll(string str, char[] charsToReplace, char replacementCharacter)
{
    if(str.IsNullOrEmpty())
    {
        return string.Empty;
    }

    var pattern = $"[{new string(charsToReplace)}]";
    return Regex.Replace(str, pattern, replacementCharacter.ToString());
}

Так что ReplaceAll("/]a", {'/', ']' }, 'a') должно вернуть "aaa".

Ответы [ 2 ]

1 голос
/ 10 января 2020

Внутри класса персонажа требуется только 4 символа, ^, -, ] и \. Вы не можете использовать Regex.Escape, потому что оно не выходит за пределы - и ], поскольку они не являются «особыми» вне класса символов. Обратите внимание, что Regex.Escape предназначен для использования только для буквенных символов (последовательностей), которые находятся за пределами классов символов.

Неэкранированный ] символ будет преждевременно закрывать ваш класс символов и это основная причина, по которой ваш код не работает.

Итак, определение фиксированной переменной pattern может выглядеть как

var pattern = $"[{string.Concat(charsToReplace).Replace(@"\", @"\\").Replace("-", @"\-").Replace("^", @"\^").Replace("]", @"\]")}]";

См. онлайн C# демо .

1 голос
/ 10 января 2020

Я предлагаю использовать Linq , а не регулярные выражения :

using System.Linq;

...

public static string ReplaceAll(
  string str, char[] charsToReplace, char replacementCharacter) 
{
   // Please, note IsNullOrEmpty syntax
   // we should validate charsToReplace as well
   if (string.IsNullOrEmpty(str) || null == charsToReplace || charsToReplace.Length <= 0)
     return str; // let's just do nothing (say, not turn null into empty string)

   return string.Concat(str.Select(c => charsToReplace.Contains(c) 
     ? replacementCharacter
     : c));
}

Если вы настаиваете на Regex (обратите внимание, что мы должны Regex.Escape символов) в пределах charsToReplace). Однако согласно руководству Regex.Escape не исключаются - и [, которые имеют специальное значение в регулярном выражении скобки .

public static string ReplaceAll(
  string str, char[] charsToReplace, char replacementCharacter) {

  if (string.IsNullOrEmpty(str) || null == charsToReplace || charsToReplace.Length <= 0)
    return str;

  string charsSet = string.Concat(charsToReplace
    .Select(c => new char[] { ']', '-' }.Contains(c) // in case of '-' and ']'
       ? $@"\{c}"                                    // escape them as well
       : Regex.Escape(c.ToString())));

  return Regex.Replace(
     str,
    $"[{charsSet}]+",
     m => new string(replacementCharacter, m.Length));
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...