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

Строка IndexOf и заменить

Сегодня я столкнулся с этой проблемой и задаюсь вопросом, может ли кто-нибудь понять, почему этот тест может потерпеть неудачу (в зависимости от культуры). Цель состоит в том, чтобы проверить, содержат ли тестовый текст два пробела рядом друг с другом, что соответствует string.IndexOf (даже если я говорю, что строка заменяет все вхождения двух пространств рядом друг с другом). После некоторого тестирования кажется, что \xAD как-то вызывает эту проблему.

public class ReplaceIndexOfSymmetryTest
{
    [Test]
    public void IndexOfShouldNotFindReplacedString()
    {
        string testText = "\x61\x20\xAD\x20\x62";
        const string TWO_SPACES = "  ";
        const string ONE_SPACE = " ";
        string result = testText.Replace(TWO_SPACES, ONE_SPACE);
        Assert.IsTrue(result.IndexOf(TWO_SPACES) < 0);
    }
}
4b9b3361

Ответ 1

Да, раньше я сталкивался с тем же (хотя с разными персонажами). В основном IndexOf будет учитывать различные аспекты "специальных" символов Юникода при поиске совпадений, тогда как Replace просто обрабатывает строки как последовательность кодовых точек.

Из IndexOf docs:

Этот метод выполняет поиск по словам (чувствительный к регистру и чувствительный к культуре) поиск с использованием текущей культуры. Поиск начинается с первой позиции символа этого экземпляра и продолжается до последней позиции символа.

... и Replace:

Этот метод выполняет порядковый (чувствительный к регистру и нечувствительный к культуре) поиск, чтобы найти oldValue.

Вы можете использовать перегрузку IndexOf, которая принимает StringComparison и заставляет ее выполнять порядковое сравнение.

Ответ 2

Как сказал Джон, используйте StringComparison.Ordinal, чтобы понять это.

Assert.IsTrue(result.IndexOf(TWO_SPACES, StringComparison.Ordinal) < 0);