C# Удалить повторяющиеся символы из строки

Имеется, допустим, 5 текстбоксов. И один главный. По мере заполнения тех пяти текстбоксов, в главном формируется имя. Между значениями текстбоксов используются знаки нижнего подчеркивания "_".

Например:

текстбокс1: 123

текстбокс2: 456

текстбокс3: 789

текстбокс4: аа

текстбокс5: бб

Главный тексбокс отобразит: 123_456_789_аа_бб

В чем проблема: для создания имени не всегда нужно заполнять все тексбоксы. Иногда достаточно одного или двух.
Тогда мы видим следующее: 123_456___ или __789__

Каким образом можно сделать, чтобы в строке при наличии двух подряд и более нижних подчеркиваний оставалось только одно. Исходя из примеров выше вывело бы 123_456 и 789.

К тому же тут для примера указал,что их 5. В реальности их может быть 10-15.

Что пробовал: Методы Trim(), Replace(), Remove() и т.д. Но решения так и не нашел. Либо удаляет нужные, либо не верно срабатывают.

UPDATE:

Для формирования итогового имени использую подобную структуру:

string fileName = tb_1.Text + "_" + tb_2.Text + "_" + tb_3.Text + "_" + tb_4.Text + "_" + cb_1.Text + "_" + cb_2.Text + "_" + cb_3.Text + "_" + cb_4.Text + "_" + cb_6.Text + "_" + tb_5.Text + "_" + tb_6.Text + "_" + tb_7.Text;

tb_FullName.Text = fileName;

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


Ответы (1 шт):

Автор решения: aepot

Например так.

Берете список

List<string> lines = new List<string>();

Добавляете в него все нужные значения

lines.Add(textBox1.Text);
lines.Add(textBox2.Text);
//...

Дальше у вас 2 варианта:

Либо сразу использовать Linq

string result = string.Join("_", lines.Where(s => s?.Length > 0));

Либо предварительно императивно в цикле надо удалить пустые строки

for (int i = 0; i < lines.Count; i++)
{
    if (string.IsNullOrEmpty(lines[i]))
    {
        lines.RemoveAt(i);
        i--;
    }
}
string result = string.Join("_", lines);

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


Однострочник для вашего конкретного случая, с использованием массива вместо списка, но разницы нет.

tb_FullName.Text = string.Join("_", new string[] { tb_1.Text, tb_2.Text, tb_3.Text, tb_4.Text, cb_1.Text, cb_2.Text, cb_3.Text, cb_4.Text, cb_6.Text, tb_5.Text, tb_6.Text, tb_7.Text }.Where(s => s?.Length > 0));
→ Ссылка