Удалить все "невидимые" символы из строки? - PullRequest
7 голосов
/ 14 марта 2011

Я пишу небольшой класс, чтобы прочитать список пар ключ-значение из файла и записать в Dictionary<string, string>.Этот файл будет иметь следующий формат:

key1:value1
key2:value2
key3:value3
...

Это должно быть довольно легко сделать, но, поскольку пользователь собирается редактировать этот файл вручную, как я должен иметь дело с пробелами, вкладками, дополнительными переходами строки и прочимкак это?Я, вероятно, могу использовать Replace для удаления пробелов и вкладок, но есть ли какие-то другие «невидимые» символы, которые мне не хватает?

Или, может быть, я могу удалить все символы, которые не являются буквенно-цифровыми, ":" и переходы строки (поскольку переходы строки - это то, что отличает одну пару от другой), а затем удалить все дополнительные переходы строки.Если это так, я не знаю, как удалить символы «все, кроме некоторых».

Конечно, я могу также проверять наличие ошибок, таких как «ключ1: значение1: что-то другое».Но такие вещи не имеют большого значения, потому что это, очевидно, ошибка пользователя, и я просто покажу сообщение «Неверный формат».Я просто хочу разобраться с основными вещами, а затем поместить все это в блок try / catch на случай, если что-то пойдет не так.

Примечание: Мне НЕ нужны какие-либо пробелы вообщедаже внутри ключа или значения.

Ответы [ 7 ]

16 голосов
/ 14 марта 2011

Я сделал это недавно, когда, наконец, разозлился из-за слишком большого количества недокументированного мусора, из-за которого в канале появлялся плохой xml. Он эффективно удаляет все, что не попадает между пробелом и ~ в таблице ASCII:

static public string StripControlChars(this string s)
{
    return Regex.Replace(s, @"[^\x20-\x7F]", "");
}

В сочетании с другими уже опубликованными примерами RegEx это должно привести вас к тому, чего вы хотите.

7 голосов
/ 14 марта 2011

Если вы используете Regex (регулярные выражения), вы можете отфильтровать все это с помощью одной функции.

string newVariable Regex.Replace (variable, @ "\ s", "");

Это удалит пробелы, невидимые символы, \ n и \ r.

4 голосов
/ 14 марта 2011

Одним из «белых» пространств, которые регулярно нас кусают, является неразрушимое пространство.Также наша система должна быть совместима с MS-Dynamics, что намного более ограничительно.Сначала я создал функцию, которая отображает 8-битные символы в их приблизительный 7-битный аналог, затем я удалил все, что не входило в диапазон от x20 до x7f, дополнительно ограниченный интерфейсом Dynamics.

Regex.Replace(s, @"[^\x20-\x7F]", "")

должен делатьэта работа.

2 голосов
/ 14 марта 2011

Требования слишком нечеткие.Подумайте:

"Когда пробел является значением? Ключ?""Когда разделитель является значением? Ключ?""Когда вкладка является значением? Клавиша?"«Где заканчивается значение, когда в контексте значения используется ключ-разделитель?»?

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

Определите простую грамматику и уберите большую часть догадок.

"{key}": "{value}",

Здесь у вас есть пара ключ / значение, заключенная в кавычки и разделенная разделителем (,).Все посторонние персонажи можно игнорировать.Вы можете использовать XML, но это может отпугнуть менее опытных пользователей.

Обратите внимание, кавычки являются произвольными.Не стесняйтесь заменять любым набором контейнеров, который не будет нуждаться в большом количестве (просто остерегайтесь сложности).

Лично я бы обернул это в простой интерфейс и сериализовал бы данные в виде XML.Есть моменты, чтобы этого не делать, но вы не дали мне повода не делать этого.

2 голосов
/ 14 марта 2011

Вы можете использовать string.Trim() для удаления символов пробела:

var results = lines
        .Select(line => {
            var pair = line.Split(new[] {':'}, 2);
            return new {
                Key = pair[0].Trim(),
                Value = pair[1].Trim(),
            };
        }).ToList();

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

var whiteSpaceRegex = new Regex(@"\s+", RegexOptions.Compiled);
var results = lines
        .Select(line => {
            var pair = line.Split(new[] {':'}, 2);
            return new {
                Key = whiteSpaceRegex.Replace(pair[0], string.Empty),
                Value = whiteSpaceRegex.Replace(pair[1], string.Empty),
            };
        }).ToList();
2 голосов
/ 14 марта 2011
var split = textLine.Split(":").Select(s => s.Trim()).ToArray();

Функция Trim () удалит все ненужные пробелы.Обратите внимание, что это сохраняет пробелы внутри ключа или значения, которые вы можете рассмотреть отдельно.

0 голосов
/ 14 марта 2011

Если это не должно быть быстро, вы можете использовать LINQ:

string clean = new String(tainted.Where(c => 0 <= "ABCDabcd1234:\r\n".IndexOf(c)).ToArray());
...