Как удалить все символы из строки, кроме букв, цифр и дефиса, в C#?
Решение с помощью регулярного выражения
Ваша задача решается очень просто с помощью класса Regex из пространства имён System.Text.RegularExpressions. Главная проблема в вашем шаблоне — вы не учли пробелы и кириллицу. Вот правильный паттерн:
using System;
using System.Text.RegularExpressions;
string input = "Hello-World! How are you? (test) 123-456 #2024 Привет-Мир!";
string result = Regex.Replace(input, @"[^a-zA-Zа-яА-Я0-9\s-]", "");
Console.WriteLine(result);
// Вывод: Hello-World How are you test 123-456 2024 Привет-Мир
Объяснение шаблона
Разберём регулярное выражение [^a-zA-Zа-яА-Я0-9\s-]:
[^...]— символ отрицания. Означает "любой символ, кроме перечисленных".a-zA-Z— все латинские буквы (строчные и заглавные).а-яА-Я— все русские буквы (строчные и заглавные). Важно: используйте именно русские 'а' и 'я', а не английские.0-9— все цифры.\s— любой пробельный символ (пробел, табуляция, перевод строки).-— сам дефис. Его нужно ставить в конце или начале диапазона, чтобы он не воспринимался как указатель диапазона.
Таким образом, Regex.Replace заменяет все символы, НЕ входящие в указанный набор, на пустую строку (удаляет их).
Альтернатива без регулярных выражений (для производительности)
Если вы обрабатываете очень много строк и производительность критична, можно использовать цикл с StringBuilder:
using System;
using System.Text;
string input = "Hello-World! How are you? (test) 123-456 #2024";
var sb = new StringBuilder(input.Length);
foreach (char c in input)
{
if (char.IsLetterOrDigit(c) || c == '-' || char.IsWhiteSpace(c))
{
sb.Append(c);
}
}
string result = sb.ToString();
Console.WriteLine(result);
// Вывод: Hello-World How are you test 123-456 2024
Этот метод работает быстрее на больших объёмах данных, но требует больше кода. Метод char.IsLetterOrDigit автоматически распознаёт буквы всех алфавитов, включая кириллицу.
Важные замечания
- Если нужно сохранить только один пробел между словами (убрать лишние), добавьте после очистки:
result = Regex.Replace(result.Trim(), @"\s+", " "); - Если дефис должен быть только внутри слов (не в начале или конце), обработайте отдельно:
result = result.Trim('-'); - Для .NET Core 3.0+ можно использовать
Regex.Replace(input, @"[^\w\s-]", ""), где\wвключает буквы, цифры и подчёркивание. Но\wне включает кириллицу в старых версиях .NET, так что будьте осторожны.
Выбирайте тот способ, который лучше подходит под вашу задачу. Для большинства случаев первого варианта с регулярным выражением более чем достаточно.
<<Использование LINQ для элегантного решения
Если вы предпочитаете функциональный стиль, можно использовать LINQ. Этот подход компактен и легко читается:
using System;
using System.Linq;
string input = "Hello-World! How are you? (test) 123-456 #2024";
string result = new string(input.Where(c =>
char.IsLetterOrDigit(c) || c == '-' || char.IsWhiteSpace(c)).ToArray());
Console.WriteLine(result);
// Вывод: Hello-World How are you test 123-456 2024
Метод Where фильтрует символы по условию, а ToArray() преобразует результат в массив для конструктора строки. Это чистое, декларативное решение без побочных эффектов.
Дополнительный совет: обработка дефисов
Если вам нужно удалить повторяющиеся дефисы или убрать их по краям, добавьте цепочку вызовов:
string clean = new string(input.Where(c =>
char.IsLetterOrDigit(c) || c == '-' || char.IsWhiteSpace(c)).ToArray());
// Удаляем лишние пробелы и дефисы по краям
clean = string.Join(" ", clean.Split(new[] { ' ' },
StringSplitOptions.RemoveEmptyEntries));
clean = clean.Trim('-');
Console.WriteLine(clean);
Помните: LINQ-решения могут быть чуть медленнее StringBuilder на очень больших строках (более 100 000 символов), но для типичных задач их производительности более чем достаточно.
Ответов пока нет.
Войдите чтобы оставить ответ