IndexOf и порядковые сравнения строк

Моя проблема в том, что String.IndexOf возвращает -1, Я ожидаю, что это вернется 0,

Параметры:

text знак равно C:\\Users\\User\\Desktop\\Sync\\̼ (обратите внимание на комбинацию "Чайка под комбинацией")

stringToTrim знак равно C:\\Users\\User\\Desktop\\Sync\\

Когда я проверяю индекс, используя int index = text.IndexOf(stringToTrim);, значение index является -1, Я обнаружил, что сравнение строк по порядку решило мою проблему:

int index = text.IndexOf(stringToTrim, StringComparison.Ordinal);

При чтении в режиме онлайн многие символы Юникода (например, U+00B5 и U + 03BC) отображаются на один и тот же символ, поэтому было бы неплохо расширить это и нормализовать обе строки:

int index = text.Normalize(NormalizationForm.FormKD).IndexOf(stringToTrim.Normalize(NormalizationForm.FormKD), StringComparison.Ordinal);

Это правильный подход, чтобы проверить, по какому индексу одна строка содержит все последовательные символы другой строки? Идея в том, что вы нормализуете, когда хотите проверить совпадение символов, но не нормализуете, когда хотите проверить символы по их закодированным значениям (поэтому разрешите дублировать символы)? Кроме того, может кто-нибудь объяснить, почему int index = text.IndexOf(stringToTrim); не нашли совпадения в начале строки? Другими словами, что он на самом деле делает под одеялом? Я ожидал, что он начнет поиск символов от начала строки до конца строки.

2 ответа

Решение

Поведение имеет смысл для меня. Вы используете комбинирующий символ, который комбинируется с предыдущим символом, превращая его в другого персонажа, который не будет соответствовать '\\' символ, который вы указали в конце строки поиска. Это предотвращает поиск всей строки, которую вы ищете. Если вы искали "C:\\Users\\User\\Desktop\\Sync" вместо этого он нашел бы это.

С помощью StringComparison.Ordinal говорит.NET игнорировать различные правила для символов и смотреть только на их точное порядковое значение. Кажется, это делает то, что вы хотели, так что да... это то, что вы должны делать.

"Правильный подход" полностью зависит от того, какое поведение вы хотите. Множество манипуляций со строками включает в себя текст, представляемый или предоставляемый пользователем, и должен выполняться с учетом культуры и Unicode. В других случаях это не желательно. Важно выбрать правильный подход для ваших нужд.

Да, вы должны использовать StringComparison.Ordinal чтобы гарантировать культуру игнорируется при сравнении стоимости. Это особенно необходимо для всех строк, которые считаются культуральными инвариантами "по умолчанию". Это включает в себя пути к файлам.

Когда не используется StringComparison.Ordinal) можно внести незначительные ошибки: http://msdn.microsoft.com/en-us/library/dd465121(v=vs.110).aspx

Когда культурно независимые строковые данные, такие как теги XML, теги HTML, имена пользователей, пути к файлам и имена системных объектов, интерпретируются так, как если бы они были чувствительны к культуре, код приложения может подвергаться незначительным ошибкам, низкой производительности и В некоторых случаях проблемы безопасности.

Некоторая побочная выгода StringComparison.Ordinal лучшая производительность: http://msdn.microsoft.com/en-us/library/ms973919.aspx

Другие вопросы по тегам