Парсинг Get ответа через C# нужна помощь

Dmitriy Ka

Client
Регистрация
03.05.2016
Сообщения
723
Благодарностей
474
Баллы
63
Есть задача, распарсить массив данных полученный из гет ответа и получить ID пользователей, которые удовлетворяют условиям "can_write_private_message = 1 и "time" >= 1616225731
Массив данных: прикрепил файл

Написал такой код, но почему то парсинг идет не совсем корректно, у некоторых строк сохраняется только ID как и надо, а на некоторые строки почему то "Regex rxID" не срабатывает и строки записываются полностью (а нужно только ID) Скрин 1

Да и сам код не совсем нравится, подскажите как его улучшить.
Не нравится что делаю 2 перебора сначала через foreach потом через for, думаю что можно обойтись каким то одним, но навыка не хватает.

C#:
IZennoList lstID = project.Lists["Список ID"];
lstID.Clear();


string strParsing = project.Variables["test"].Value; //Массив данных
Regex rxTime = new Regex (@"(?<=""time"":).*?(?=})"); //Получаем Time
Regex rxID = new Regex ("(?<=\"id\":).*?(?=,)"); //Получаем ID

int intTime = 1616225731;
if (Regex.IsMatch(strParsing, "\\{\"first_name\".*?}"))   
    foreach (var strGoodID in Regex.Matches(strParsing, "\\{\"first_name\".*?}"))
        if (Regex.IsMatch(strGoodID.ToString(), "(?<=\"can_write_private_message\":)1.*?(?=,)"))
            lstID.Add(strGoodID.ToString());
                for (int i = 0; i <= lstID.Count; i ++){
                    string n = lstID[0];
                    lstID.RemoveAt(0);
                    string time = rxTime.Match(n).Value;
                        if (String.IsNullOrEmpty(time)){
                        project.SendInfoToLog("Проблемная строка");
                        continue;
                        }else if (Convert.ToInt32(time) >= intTime) lstID.Add(rxID.Match(n).Value.ToString());
                    }
                
return "ok";
 

Вложения

  • 253,3 КБ Просмотры: 3
  • 229,5 КБ Просмотры: 14

volody00

Client
Регистрация
06.09.2016
Сообщения
917
Благодарностей
950
Баллы
93
только проверь корректность работы
C#:
IZennoList lstID = project.Lists["Список ID"];
lstID.Clear();

project.Json.FromString(project.Variables["test"].Value); //в переменной test у нас json, который надо раскидать по переменным
Dictionary<string, string> all = project.Json.GetAllMembersList(); //сложим всё в словарь

int kolGroup = Convert.ToInt32(all["response.items.Count"]);

for(int i=0;i<kolGroup;i++)
{
    try
    {
        if(all[$"response.items[{i}].can_write_private_message"] == "1" && Convert.ToInt32(all[$"response.items[{i}].last_seen.time"]) > 1616225731) lock(SyncObjects.ListSyncer) lstID.Add(all[$"response.items[{i}].id"]);
    }
    catch(Exception e)
    {
        project.SendWarningToLog(e.Message);
        continue;
    }
    
}
 
  • Спасибо
Реакции: Dmitriy Ka и Alexmd

nicanil

Client
Регистрация
06.03.2016
Сообщения
2 242
Благодарностей
1 819
Баллы
113
У Вас JSON и в ZennoPoster есть встроенные средства для работы с ним (ссылка на Справку).
Разбор JSON строки может занимать какое-то время (у Вас большой массив данных).

Можно и с помощью C#:
C#:
// Парсим JSON
project.Json.FromString(project.Variables["response"].Value);

for (int i=0; i<project.Json.response.items.Count; i++)
{
    // Иногда нет time. Пропускаем такие строки.
    long time = -1;
    try
    {
        time = project.Json.response.items[i].last_seen.time;
    }
    catch (Microsoft.CSharp.RuntimeBinder.RuntimeBinderException ex)
    {
        project.SendWarningToLog("Не нашли time для id "+project.Json.response.items[i].id);
        continue;
    }
    
    long can_write = project.Json.response.items[i].can_write_private_message;
    
    if (can_write == 1 && time >= 1616225731)
    {
        // Выводим в лог имя, фамилию, id людей, которые подходят по условиям.
        project.SendInfoToLog(
            String.Format("{0} {1} {2}",
                project.Json.response.items[i].first_name,
                project.Json.response.items[i].last_name,
                project.Json.response.items[i].id
            )
        );
    }
}
 
  • Спасибо
Реакции: Dmitriy Ka и SHILY

Alexmd

Client
Регистрация
10.12.2018
Сообщения
1 022
Благодарностей
1 424
Баллы
113
Для кого я в прошлый раз распинался?
Парсить json регулярками неправильно. Не делайте так.
C#:
project.Json.FromString(project.Variables["json"].Value);//переменная в которую попадает json
List<string> temp = new List<string>();
int lastSeen = int.Parse(project.Variables["lastseen"].Value);//переменная с необходимым lastseen
project.Json.FromString(project.Json.response.items.ToString());
for(int i = 0; i < project.Json.Count; i++)
    try{
        if(project.Json[i].can_write_private_message == 1)
            if(project.Json[i].last_seen.time >= lastSeen)
                temp.Add(project.Json[i].id.ToString());
    }
    catch{}
project.SendInfoToLog(temp.Count.ToString(),true);
lock(CommonCode.SyncObject){//чтобы это работало, необходимо включить общий код
    project.Lists["ids"].AddRange(temp);//список для подходящих id
}
Подставьте свои переменные и список
 

Dmitriy Ka

Client
Регистрация
03.05.2016
Сообщения
723
Благодарностей
474
Баллы
63

Alexmd

Client
Регистрация
10.12.2018
Сообщения
1 022
Благодарностей
1 424
Баллы
113
Это в проджект мейкере долго, потому что json большой, а в зенке намного быстрее все происходит.
 
  • Спасибо
Реакции: nicanil

Dmitriy Ka

Client
Регистрация
03.05.2016
Сообщения
723
Благодарностей
474
Баллы
63
Всем спасибо за помощь.
Прислушаюсь к советам и буду работать через json, не просто так все три варианта написаны на нем.
Больше всего понравился вариант от nicanil, для меня самый понятный и простой.
 
  • Спасибо
Реакции: nicanil

Кто просматривает тему: (Всего: 1, Пользователи: 0, Гости: 1)