#c# #.net #string-search
#c# #.net #поиск по строке
Вопрос:
Я обнаружил, что в некоторых случаях строка.indexOf() возвращает -1 при поиске двойного разрыва строки r n r n, когда за ним следует последовательность байтов 0xCC (204) (могут быть и другие, не проверял). Ниже приведен пример dotnetfiddle — там можно выбрать компилятор. В компиляторе netcore31 строка найдена всегда, в других компиляторах только тогда, когда за ней не следует последовательность 0xCC. Кто-нибудь может это объяснить?
https://dotnetfiddle.net/ZMW7tL
РЕДАКТИРОВАТЬ: То же самое происходит, когда я ставлю 0xCB или 0xCD после last r n.
Исходный код скрипки:
using System;
public class Program
{
public static void Main()
{
var x = new byte[] { 99, 108, 111, 115, 101, 13, 10, 13, 10, 204, 159, 67, 4 };
var z = System.Text.Encoding.UTF8.GetString(x);
Console.WriteLine(z);
Console.WriteLine();
var idx = z.IndexOf("rnrn");
Console.WriteLine("index = " idx);
Console.WriteLine("=========================");
var x1 = new byte[] { 99, 108, 111, 115, 101, 13, 10, 13, 10, 5, 159, 67, 4 };
var z1 = System.Text.Encoding.UTF8.GetString(x1);
Console.WriteLine(z1);
Console.WriteLine();
var idx1 = z1.IndexOf("rnrn");
Console.WriteLine("index modified = " idx1);
Console.WriteLine("=========================");
var x2 = new byte[] { 13, 10, 13, 10, 204, 159 };
var z2 = System.Text.Encoding.UTF8.GetString(x2);
Console.WriteLine(z2);
Console.WriteLine();
var idx2 = z2.IndexOf("rnrn");
Console.WriteLine("index short = " idx2);
}
}
Комментарии:
1. Я собираюсь предположить, что это из-за проблемы с кодировкой. У вас есть массив байтов, которые декодируются в a
string
, но 204 не является стандартным ASCII и поэтому для преобразования его в a будет использоваться кодировкаchar
.2. @Neil Я понимаю, что это не символ ASCII, но я бы ожидал, что .net проанализирует входящую строку «слева направо», и как только соответствующая подстрока найдена, возвращается ее индекс, независимо от последующих символов. Я знаю, что различные кодировки обрабатывают последовательности байтов по-разному, но я не могу точно понять, почему приведенный выше пример не работает. Итак, я ищу более подробное объяснение.
3. Допустимый UTF-8. Символ (закодированный в виде двух байт в UTF-8) представляет собой комбинирующий символ, который объединяется с символом, предшествующим ему, так что у вас есть
n
с объединениемниже. .NET Framework сравнивает объединенный символ, а не отдельные кодовые точки.
4. Хорошо, вероятно, это: utf8-chartable.de /…
5. Да, те. И даже это не полные «символы», а просто кодовые точки Unicode, которые объединяются с другими кодовыми точками для создания символов.