Оптимальный вариант парсинга строки

103
16 января 2021, 11:10

Делаю запрос на сервер, результатом является byte[] (массив байтов обозвал как data). Не знаю на сколько разумно, но для начала конвертирую в string

string result = System.Text.Encoding.UTF8.GetString(data);

И так, есть уже строка такого типа <par1="value1" par2="value2"...> К примеру, мне нужно получить значение параметра par7. Какой оптимальный вариант для этого есть? Оптимальный - самый быстрый

Answer 1

Мое решение такое:

private static void Main(string[] args)
{
    var input = @"<par1=""value1"" par2=""value2"" par7=""value7"">";
    var parameter = "par2";
    var val = GetValue(input, parameter);
    Console.WriteLine($"{parameter} = {val}");
    Console.ReadKey();
}
/// <summary>
/// Get value of param from specific string  
/// </summary>
/// <param name="input">Specific string</param>
/// <param name="sample">param name</param>
/// <returns>Value represented by string. if not found - string.Empty</returns>
private static string GetValue(string input, string sample)
{
    var isInQuotes = false; // Для определения того, находится ли текущий символ внутри кавычек
    for (int i = 0; i <= input.Length - sample.Length - 3; i++) 
    {
        if (input[i] == '"')
            isInQuotes = !isInQuotes;
        if (IsSame(input, i, sample) && !isInQuotes)
        {
            var j = i + sample.Length;
            // Идем до открывающейся кавычки
            while (input[j] != '"')
            {
                j++;
                if (j == input.Length)
                    return string.Empty;
            }
            j++;
            var sb = new StringBuilder();
            // Идем до закрытия кавычек, при этом записывая значение в stringBuilder
            while (input[j] != '"')
            {
                sb.Append(input[j++]);
                if (j == input.Length)
                    return string.Empty;
            }
            return sb.ToString();
        }
    }
    return string.Empty;
}
/// <summary>
/// Check equality of sample and src substring
/// </summary>
/// <param name="src"></param>
/// <param name="from">Start index of src</param>
/// <param name="sample"></param>
/// <returns></returns>
private static bool IsSame(string src, int from, string sample)
{
    if (from + sample.Length > src.Length)
        return false;
    for (int i = 0; i < sample.Length; i++)
    {
        if (src[from + i] != sample[i])
            return false;
    }
    return true;
}

Тестирование и ревью этого куска кода приветствуется. Я не вставлял сюда проверку входной строки на открытие/закрытие тега <>.

В остальном все проверки есть (если я ничего не упустил).

READ ALSO
UpCast/DownCast C#

UpCast/DownCast C#

В процессе изучения языка C# сталкиваюсь, как и все новички, с трудностями пониманияИзучаю язык на нескольких ресурсах, так как каждую тему...

101
Как скопировать каталоги в потоке с входными параметрами?

Как скопировать каталоги в потоке с входными параметрами?

Учусь запускать методы в потокеПодскажите как запустить метод в потоке, если в методе есть входные параметры?

116
Использовать ли оператор return , если функция ничего не возвращает?

Использовать ли оператор return , если функция ничего не возвращает?

Нужно ли использовать оператор return в функции, тип возвращаемого значения которой указан как void, или же его просто опускать? В чем разница...

113