Подтвердить что ты не робот

Почему в результате запроса отсутствует один символ?

Взгляните на код:

string expression = "x & ~y -> (s + t) & z";
var exprCharsNoWhitespace = expression.Except( new[]{' ', '\t'} ).ToList();
var exprCharsNoWhitespace_2 = expression.Replace( " ", "" ).Replace( "\t", "" ).ToList();

// output for examination
Console.WriteLine( exprCharsNoWhitespace.Aggregate( "", (a,x) => a+x ) );
Console.WriteLine( exprCharsNoWhitespace_2.Aggregate( "", (a,x) => a+x ) );

// Output:
// x&~y->(s+t)z
// x&~y->(s+t)&z

Я хочу удалить все пробелы из исходной строки, а затем получить отдельные символы. Результат удивил меня. Переменная exprCharsNoWhitespace содержит, как и ожидалось, пробелы, но неожиданно, только почти все остальные символы. Последнее появление "&" отсутствует, подсчет списка равен 12. В то время как exprCharsNoWhitespace_2 полностью соответствует ожидаемому: Count равно 13, все символы, кроме пробелов, содержатся.

Используемая среда была .NET 4.0. Я также просто вложил это в csharppad (веб-IDE/компилятор) и получил те же результаты.

Почему это происходит?


ИЗМЕНИТЬ: Хорошо, я не знал, что, кроме того, как указал Райан О'Хара, операция была завершена. Раньше я не использовал его.

// So I'll continue just using something like this:
expression.Where( c => c!=' ' && c!='\t' )

// or for more characters this can be shorter: 
expression.Where( c => ! new[]{'a', 'b', 'c', 'd'}.Contains(c) ).
4b9b3361

Ответ 1

Except создает разницу в настройках. Ваше выражение не является набором, поэтому его не правильный метод для использования. Что касается того, почему отсутствует &: его, потому что он повторяется. Ни один из других символов не указан.

Ответ 2

Райан уже ответил на ваш вопрос по заданию, но я хотел бы предоставить вам альтернативное решение проблемы, с которой вы столкнулись. Если вам нужно сделать много манипуляций с строками, вы можете найти правильное соответствие шаблону выражения, чтобы быть полезным. Примеры, которые вы указали, будут работать примерно так:

string expression = "x & ~y -> (s + t) & z";
string pattern = @"\s";
string replacement = "";
string noWhitespace = new Regex(pattern).Replace(expression, replacement);

Или для второго примера сохраните все одинаковое, кроме шаблона:

string pattern = "[abcd]";

Храните объект Regex где-то, а не создавайте его каждый раз, если вы собираетесь использовать тот же шаблон много.

Ответ 3

Как уже упоминалось, .Except(...) представляет собой заданную операцию, поэтому он удаляет дубликаты.

Попробуйте использовать .Where(...) вместо этого:

string expression = "x & ~y -> (s + t) & z";
var exprCharsNoWhitespace =
    String.Join(
        "",
        expression.Where(c => !new[] { ' ', '\t' }.Contains(c)));

Это дает:

x&~y->(s+t)&z