Специальные символы Regex

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

        public void fd()
        {
            string output = "";
            string input = Console.ReadLine();
            char[] charArray = input.ToCharArray();

            foreach (var item in charArray)
            {

                if (!Char.IsLetterOrDigit(item))
                {

                   \\\CODE HERE                    }

            }

            output = new string(trimmedChars);
            Console.WriteLine(output);
        }

В конце я превращаю его обратно в строку. Мой код удаляет только один специальный символ в строке. У кого-нибудь есть предложения по более простому пути?

3 ответа

Решение

Проблема с вашим кодом в том, что вы берете данные из charArray и положить результат в trimmedChars для каждого внесенного вами изменения, поэтому каждое изменение будет игнорировать все предыдущие изменения и работать с оригиналом. В конце у вас есть только последнее изменение.

Другая проблема с кодом заключается в том, что вы используете IndexOf чтобы получить индекс символа, но он получит индекс первого вхождения этого символа, а не индекс, в котором вы получили этот символ. Например, когда вы находитесь на втором ! в строке "foo!bar!" Вы получите индекс первого.

Вам не нужно превращать строку в массив для работы с символами в строке. Вы можете просто пройтись по индексу символов в строке.

Обратите внимание, что вы также должны проверять значение индекса, когда смотрите на символы до и после, чтобы не пытаться смотреть на символы, находящиеся за пределами строки.

public void fd() {
  string input = Console.ReadLine();
  int index = 0;
  while (index < input.Length) {
    if (!Char.IsLetterOrDigit(input, index) && ((index == 0 || !Char.IsLetterOrDigit(input, index - 1)) || (index == input.Length - 1 || !Char.IsLetterOrDigit(input, index + 1)))) {
      input = input.Remove(index, 1);
    } else {
      index++;
    }
  }
  Console.WriteLine(input);
}

У вас хорошая реализация, просто подумайте об использовании следующего кода, который немного короче, но имеет немного более высокие абстракции

var input =  " th@ere's! ";

Func<char, bool> isSpecialChar = ch => !char.IsLetter(ch) && !char.IsDigit(ch);

for (int i = 1; i < input.Length - 1; i++)
{
    //if current character is a special symbol
    if(isSpecialChar(input[i])) 
    {
        //if previous or next character are special symbols
        if(isSpecialChar(input[i-1]) || isSpecialChar(input[i+1]))
        {
            //remove that character
            input = input.Remove(i, 1);
            //decrease counter, since we removed one char
            i--;
        }
    }
}
Console.WriteLine(input); //prints " th@ere's "

Новая строка будет создаваться при каждом вызове Remove, Использовать StringBuilder для более производительного по памяти решения.

Прошло некоторое время с тех пор, как я попал на C#, но может помочь reg ex

string input = string.Format("{0}! ", Console.ReadLine());
Regex rgx = new Regex("(?i:[^a-z]?)[.](?i:[^a-z]?)");
string output = rgx.Replace(input, "$1$2");

Регулярное выражение ищет символ с не-альфа-символом слева или справа и заменяет его ничем.

Другие вопросы по тегам