Строка 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);
}
}
Ответы
Ответ 1
Да, раньше я сталкивался с тем же (хотя с разными персонажами). В основном IndexOf
будет учитывать различные аспекты "специальных" символов Юникода при поиске совпадений, тогда как Replace
просто обрабатывает строки как последовательность кодовых точек.
Из IndexOf
docs:
Этот метод выполняет поиск по словам (чувствительный к регистру и чувствительный к культуре) поиск с использованием текущей культуры. Поиск начинается с первой позиции символа этого экземпляра и продолжается до последней позиции символа.
... и Replace
:
Этот метод выполняет порядковый (чувствительный к регистру и нечувствительный к культуре) поиск, чтобы найти oldValue.
Вы можете использовать перегрузку IndexOf
, которая принимает StringComparison
и заставляет ее выполнять порядковое сравнение.
Ответ 2
Как сказал Джон, используйте StringComparison.Ordinal
, чтобы понять это.
Assert.IsTrue(result.IndexOf(TWO_SPACES, StringComparison.Ordinal) < 0);