строка.IndexOf () не распознает измененные символы

при использовании IndexOf чтобы найти символ, за которым следует большой значимый символ (например, char 700, который является'), тогда IndexOf не удается распознать символ, который вы ищете.

например

string find = "abcʼabcabc";   
int index = find.IndexOf("c");

в этом коде индекс должен быть 2, но он возвращает 6.

есть ли способ обойти это?

2 ответов


на конструкция обрабатывается как лингвистически отличаются от простых байтов. Используйте сравнение порядковых строк для принудительного сравнения байтов.

        string find = "abcʼabcabc";

        int index = find.IndexOf("c", StringComparison.Ordinal);

буква Юникода 700-это модификатор Апостроф: другими словами, он изменяет букву c. Точно так же, если бы вы использовали "e", а затем символ 769 (0x301), это больше не будет "e": e был изменен, чтобы быть e с острым акцентом. А именно: é. Вы увидите, что письмо на самом деле два символа: скопируйте его в блокнот и нажмите backspace (аккуратно, да?).

вам нужно сделать "порядковое" сравнение (байт за байтом) без любое лингвистическое сравнение. Это найдет " c " и проигнорирует лингвистический факт, что он изменен следующей буквой. В моем примере " e " байты (65) (769), поэтому, если вы идете байт за байтом в поисках 65, вы найдете его, и это игнорирует тот факт, что(65) (769) лингвистически то же самое, что и (233): é. Если вы ищете (233) лингвистически, он найдет "эквивалент" (65)(769):

string find = "abéabcabc";
int index = find.IndexOf("é"); //gives you '2' even though the "find" has two characters and the the "indexof" is one

надеюсь, это не слишком запутанным. Если вы делаете это в реальном коде вы должны объясните в комментариях, что именно вы делаете: как и в моем примере "e", как правило, вы хотели бы сделать семантическую эквивалентность для пользовательских данных и порядковую эквивалентность для, например, констант (которые, надеюсь, не будут отличаться от этого, чтобы ваш преемник выследить вас с топором).