Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.58/40: Рейтинг темы: голосов - 40, средняя оценка - 4.58
 Аватар для Jman
89 / 77 / 38
Регистрация: 11.10.2015
Сообщений: 860

Разобрать строку (распарсить)

28.11.2016, 11:08. Показов 7671. Ответов 35
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Всем привет, как можно правильно распарсить строку приерного вида?
msg = "temp1 = 25C, temp2=33, humidity = 85, light level = 57 \r";

Делаю вот так:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
 [STAThread]
        private void DisplayLabelData(MessageType type, string msg)
        {
           
            string [] separatedCommaMessage = msg.Split(new char[] { ',' });
 
            lbInsideTemperature.Invoke(new EventHandler(delegate
            {
                if (comPort.IsOpen)
                {
                    lbInsideTemperature.Text = string.Empty;
                    lbInsideTemperature.Font = new Font(lbInsideTemperature.Font, FontStyle.Bold);
                    lbInsideTemperature.ForeColor = MessageColor[(int)type];
                    foreach (string s in separatedCommaMessage)
                           lbInsideTemperature.Text = s;
                                       
                }
                // Если порт закрыт, очищаем поле;
                else lbInsideTemperature.Text = string.Empty;
            }));
В итоге у меня выводится в лейбл не первая подстрока, а вторая temp2=33

Добавлено через 5 минут
Либо последняя....
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
28.11.2016, 11:08
Ответы с готовыми решениями:

Распарсить строку
Суть вопроса такова, есть тест: MyName is: Brain So, bla bla Мне нужно спарсить Brain

Распарсить строку
Доброго времени суток. У меня есть строка вида: "{var1}{var2}const1{var3}const2" Мне нужно её распарсить и получить на выходе {var1} ...

Распарсить строку
Здравствуйте подскажите пожалуйста регулярное выражение для того чтобы распарсить строку вида : ...

35
Эксперт .NET
 Аватар для Usaga
14293 / 9378 / 1352
Регистрация: 21.01.2016
Сообщений: 35,360
28.11.2016, 11:16
Jman, у тебя в лейбл, по очереди, записываются все полученные тобой строки. Каждое последующе переписывает предыдущее значение:

C#
1
2
foreach (string s in separatedCommaMessage)
    lbInsideTemperature.Text = s;
В результате, в метке останется только значение записанное последним.
0
Хитрая блондиночка $)
 Аватар для Hikari
1472 / 988 / 399
Регистрация: 21.12.2015
Сообщений: 3,785
28.11.2016, 11:24
С коленки:
C#
1
2
3
4
5
            string msg = "temp1 = 25C, temp2=33, humidity = 85, light level = 57 \r";
            var param = msg.Split(',').Select(i => i.Split('=')).Select(j => new { Name = j[0], Value = j[1] });
            foreach (var i in param) {
                Console.WriteLine("Имя={0}\tЗначение={1}", i.Name, i.Value);
            }
Хотя может в C# есть что-то вроде Делфийского TStringList...
1
 Аватар для Jman
89 / 77 / 38
Регистрация: 11.10.2015
Сообщений: 860
28.11.2016, 11:32  [ТС]
Цитата Сообщение от Usaga Посмотреть сообщение
у тебя в лейбл, по очереди, записываются все полученные тобой строки. Каждое последующе переписывает предыдущее значение:
Окей, мне тогда лучше применить subString?
0
Эксперт .NET
 Аватар для Usaga
14293 / 9378 / 1352
Регистрация: 21.01.2016
Сообщений: 35,360
28.11.2016, 11:33
Цитата Сообщение от Jman Посмотреть сообщение
Окей, мне тогда лучше применить subString?
Зачем? Ты и так уже на руки полчил массив строк с нужными тебе значениями.
0
 Аватар для Jman
89 / 77 / 38
Регистрация: 11.10.2015
Сообщений: 860
28.11.2016, 11:34  [ТС]
Как их отфильтровать? по порядку тогда? Тямы не хватает. Лейблов аж 4ре =)
0
Эксперт .NET
 Аватар для Usaga
14293 / 9378 / 1352
Регистрация: 21.01.2016
Сообщений: 35,360
28.11.2016, 11:38
Jman, перебирай полученный массив в цикле, проверяй что содержится в данной строке (через String.Contains()) и, присваивай значение соответствующему лейблу.
0
 Аватар для Jman
89 / 77 / 38
Регистрация: 11.10.2015
Сообщений: 860
28.11.2016, 11:44  [ТС]
Покажите пожалуйста на примере... Если не трудно.
0
Эксперт .NET
 Аватар для Usaga
14293 / 9378 / 1352
Регистрация: 21.01.2016
Сообщений: 35,360
28.11.2016, 11:54
Лучший ответ Сообщение было отмечено Jman как решение

Решение

Jman, ну как-то так:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
        private void DisplayLabelData(MessageType type, string msg)
        {
           
            string [] separatedCommaMessage = msg.Split(new char[] { ',' });
 
            lbInsideTemperature.Invoke(new EventHandler(delegate
            {
                if (comPort.IsOpen)
                {
                    foreach (string s in separatedCommaMessage)
                    {
                        if (s.Contains("temp1"))
                        {
                            lbInsideTemperature.Text = s;
                        } else if (s.Contains("temp2"))
                        {
                            lbOtherTemperature.Text = s;
                        } else if (s.Contains("humidity"))
                        {
                            lbHumidity.Text = s;
                        }
                    }
 
                }
                // Если порт закрыт, очищаем поле;
                else lbInsideTemperature.Text = string.Empty;
            }));
Подразумевается, что лейблы с такими названиями существуют
0
 Аватар для Jman
89 / 77 / 38
Регистрация: 11.10.2015
Сообщений: 860
28.11.2016, 11:58  [ТС]
Получается код будет завязан на строки. Если мне необходимо будет изменить в принимаемых данных, придется везде корректировать значение подстрок.

Добавлено через 1 минуту
И да, что это такое? Сделал по примеру, но не понимаю, на делегат не похоже.
C#
1
lbInsideTemperature.Invoke(new EventHandler(delegate
0
Эксперт .NET
 Аватар для Usaga
14293 / 9378 / 1352
Регистрация: 21.01.2016
Сообщений: 35,360
28.11.2016, 12:00
Jman, объяви класс со строками-константами, и используй его везде.

C#
1
2
3
4
5
6
7
8
public static ParameterNames {
    public const string TEMP1 = "temp1";
    public const string HUMIDITY = "humidity";
}
 
// Где-то в коде...
if (s.Contains(ParameterNames.HUMIDITY)) {
 ...
Добавлено через 42 секунды
Цитата Сообщение от Jman Посмотреть сообщение
И да, что это такое? Сделал по примеру, но не понимаю, на делегат не похоже.
Это делегат.
1
 Аватар для Jman
89 / 77 / 38
Регистрация: 11.10.2015
Сообщений: 860
28.11.2016, 12:01  [ТС]
Спасибо! Вы даете очень ценные советы. Такой вопрос... После слова темп идет значение, оно будет всегда изменятся, как его выводить в лейбл данным способом, что вы показали выше?
0
Эксперт .NET
 Аватар для Usaga
14293 / 9378 / 1352
Регистрация: 21.01.2016
Сообщений: 35,360
28.11.2016, 12:11
Jman, ну, либо выводить как оно есть (например "temp1=87.1"), либо разбивать (String.Split) по знаку "=" и выводить значение с индексом 1 (т.е. ту половину, что идёт после знака равенства).

Можно использовать для этих целей регулярные выражения. Тогда из исходной строки сразу можно будет выдёргивать необходимые значения.
0
 Аватар для Jman
89 / 77 / 38
Регистрация: 11.10.2015
Сообщений: 860
28.11.2016, 12:12  [ТС]
Может я неправильным путем иду. У меня есть строка с динамическими данными вида:
"temp1 = 25C, temp2=33, humidity = 85, light level = 57
Которая шурует в ком порт ПК. Я ее разбиваю на 4 лейбла и вывожу. Это правильный подход? Данные будут изменяться в реальном времени.
Можно использовать для этих целей регулярные выражения
Тут я нуб полный. Это видимо то что предложил Hikari
0
Эксперт .NET
 Аватар для Usaga
14293 / 9378 / 1352
Регистрация: 21.01.2016
Сообщений: 35,360
28.11.2016, 12:18
Лучший ответ Сообщение было отмечено Jman как решение

Решение

Jman, примерно так:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
using System;
using System.Text.RegularExpressions;
 
namespace NETExperiments
{
    class Program
    {
        static void Main(string[] args)
        {
            int humidity = 0;
            string source =
                "temp1 = 25C, temp2=33, humidity = 85, light level = 57 \r";
 
            Regex reg = new Regex("humidity[\\s]?=[\\s]?([\\d]+)");
 
            Match match = reg.Match(source);
 
            if (match.Success)
            {
                humidity = Int32.Parse(match.Groups[1].Value);
            }
 
            Console.WriteLine(humidity);
 
            Console.ReadKey();
        }
    }
}
Добавлено через 2 минуты
Jman, по-хорошему, нужно держать в коде некий класс (модель данных), в котором должны содержаться полученные значения. Записывать туда эти значения нужно только раз - при получении данных от устройства. И потом можно будет где угодно и как угодно эти данные отображать. Хоть в консоль, хоть в метку, хоть на странице...
0
 Аватар для Jman
89 / 77 / 38
Регистрация: 11.10.2015
Сообщений: 860
28.11.2016, 12:36  [ТС]
Спасибо! Все работает! Скажите пожалуйста, для остальных лейблов если сделать (пока без отдельного класса, что бы отладить), придется делать копии делегатов только для разных лейблов?
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
 private void DisplayLabelData(MessageType type, string msg)
        {
           
           // string [] separatedCommaMessage = msg.Split(new char[] { ' ' });
 
            lbInsideTemperature.Invoke(new EventHandler(delegate
            {
                if (comPort.IsOpen)
                {
                    lbInsideTemperature.Text = string.Empty;
                    lbInsideTemperature.Font = new Font(lbInsideTemperature.Font, FontStyle.Bold);
                    lbInsideTemperature.ForeColor = MessageColor[(int)type];
                    //Выводим все из порта;
                    //lbInsideTemperature.Text = msg;
                    //var param = msg.Split(',').Select(i => i.Split('=')).Select(j => new { Name = j[0], Value = j[1] });
                    //foreach (var i in param)
                    //    lbInsideTemperature.Text = i.Name;
                    int humidity = 0;
                    Regex reg = new Regex("humidity[\\s]?=[\\s]?([\\d]+)");
                    Match match = reg.Match(msg);
 
                    if (match.Success)
                    {
                        humidity = Int32.Parse(match.Groups[1].Value);
                    }
 
                    lbInsideTemperature.Text = Convert.ToString(humidity);
                }
                // Если порт закрыт, очищаем поле;
                else lbInsideTemperature.Text = string.Empty;
            }));
            
         }
0
Эксперт .NET
 Аватар для Usaga
14293 / 9378 / 1352
Регистрация: 21.01.2016
Сообщений: 35,360
28.11.2016, 12:48
Jman, нет. Метод Invoke() выполняет код делегата в UI-потоке. Можно весь код поместить в один делегат, только разбить на методы для каждого лейбла, что бы каши из кода не было.
0
 Аватар для Jman
89 / 77 / 38
Регистрация: 11.10.2015
Сообщений: 860
28.11.2016, 13:21  [ТС]
Получается что мне нужно будет создавать еще методы в методе
C#
1
 private void DisplayLabelData(MessageType type, string msg)
0
Эксперт .NET
 Аватар для Usaga
14293 / 9378 / 1352
Регистрация: 21.01.2016
Сообщений: 35,360
28.11.2016, 13:39
Jman, ты можешь всё поместить в один Invoke(). Просто куча кода в одном месте будет. Некрасиво. Распарси строку с параметрами, а потом в Invoke задай значение всем лейблам разом. Парсинг разбей на четыре части, по методу на параметр.
0
 Аватар для Jman
89 / 77 / 38
Регистрация: 11.10.2015
Сообщений: 860
28.11.2016, 14:27  [ТС]
Так, вот так пойдет? Правильно - ли?
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
private int ParseInsideTemperature(string msg)
        {
            int inTemp = 0;
 
            Regex intReg = new Regex("temp1[\\s]?=[\\s]?([\\d]+)");
            Match match = intReg.Match(msg);
 
            if (match.Success)
            {
                inTemp = Int32.Parse(match.Groups[1].Value);
            }
            return inTemp;
        }
Делегат
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
private void DisplayLabelData(MessageType type, string msg)
                {
 
                   // string [] separatedCommaMessage = msg.Split(new char[] { ' ' });
 
                    lbInsideTemperature.Invoke(new EventHandler(delegate
                    {
                        if (comPort.IsOpen)
                        {
                            lbInsideTemperature.Text = string.Empty;
                            lbInsideTemperature.Font = new Font(lbInsideTemperature.Font, FontStyle.Bold);
                            lbInsideTemperature.ForeColor = MessageColor[(int)type];
                            lbInsideTemperature.Text = Convert.ToString(ParseInsideTemperature(msg));
 
                            //Выводим все из порта;
                          //  lbInsideTemperature.Text = Convert.ToString(inTemp);
 
                        }
                        // Если порт закрыт, очищаем поле;
                        else lbInsideTemperature.Text = string.Empty;
                    }));
 
                 }
Почему-то ноль..
В консоли вроде работает
C#
1
2
string source =
                "temp1 = 25, temp2=33, humidity = 85, light level = 57 \r";
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
static int ParseInsideTemperature(string msg)
        {
            int inTemp = 0;
 
            Regex intReg = new Regex("temp1[\\s]?=[\\s]?([\\d]+)");
            Match match = intReg.Match(msg);
 
            if (match.Success)
            {
                inTemp = Int32.Parse(match.Groups[1].Value);
            }
            return inTemp;
        }
main:
C#
1
Console.WriteLine(ParseInsideTemperature(source));
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
28.11.2016, 14:27
Помогаю со студенческими работами здесь

Распарсить строку
Здравствуйте ув.форумчани! Помогите пожалуйста с регуляркой. Имеется вот такой вот текст: <table...

Распарсить строку
String s = "`user999` | 1882 "; string pattern = @"(\d)+"; RegexOptions option = RegexOptions.IgnoreCase; ...

Распарсить строку
Всем вечер добрый, господа. Есть такая беда. Есть строка. И она меняется(!)...Однако символы ( & И ; - не меняются.) Допустим...

Распарсить строку
Доброго времени суток, подскажите как можно распарсить следующую строку ...

Как распарсить строку?
Всем привет! У меня есть строка: <div class="work-info"> <!----> <!----><div class="work-description break-text"...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11680&d=1772460536 Одним из. . .
Реалии
Hrethgir 01.03.2026
Нет, я не закончил до сих пор симулятор. Эта задача сложнее. Не получилось уйти в плавсостав, но оно и к лучшему, возможно. Точнее получалось - но сварщиком в палубную команду, а это значит, в моём. . .
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
SDL3 для Web (WebAssembly): Сборка библиотек: SDL3, Box2D, FreeType, SDL3_ttf, SDL3_mixer и SDL3_image из исходников с помощью CMake и Emscripten
8Observer8 27.02.2026
Недавно вышла версия 3. 4. 2 библиотеки SDL3. На странице официальной релиза доступны исходники, готовые DLL (для x86, x64, arm64), а также библиотеки для разработки под Android, MinGW и Visual Studio. . . .
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru