Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / C++ [игнор отключен] [закрыт для гостей] / Парсинг строки с++ / 19 сообщений из 19, страница 1 из 1
04.07.2016, 17:25
    #39267561
Serega325
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Парсинг строки с++
Здравствуйте, помогите пожалуйста распарсить строку на с++.
Мне надо из строки "Select VDC col_3 where col_1 = 200m and col_2 = 300m and col_3 = 400m and col_4 = AA and col_5 = B3B and col_6=4C4" вытащить 200m, 300m, 400m, AA, B3B, 4C4

Пробовал сделать таким образом, но ничего не выходит.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
std::string str = "Select VDC col_3 where col_1 = 200m and col_2 = 300m and col_3 = 400m and col_4 = AA and col_5 = B3B and col_6=4C4"
		while (str.length() > 0)
		{
			std::tr1::regex rx("(=\x020*[-+]?[0-9]+[\.\,]?[0-9]+(([eE][-+]?[0-9]+)|((p)|(u)|(m)|(k)|(M)|(G)|(п)|(мк)|(м)|(к)|(М)|(Г)))?)|(=\x020*\w+)");
			std::tr1::regex_search(str.c_str(), res, rx);			
		size_t pos = str.find(res[0].str().c_str());
			//printf("%d. Str = %s\n", k, str.c_str());
			str = str.substr(pos+res[0].length()).c_str();			
		printf("Resalt : %s  length = %d  pos = %d \n ",res[0].str().c_str(),res[0].length(),pos);
			if (res[0].length() <= 0)
			         str.clear();
                }
...
Рейтинг: 0 / 0
04.07.2016, 17:35
    #39267572
Serega325
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Парсинг строки с++
Serega325Здравствуйте, помогите пожалуйста распарсить строку на с++.
Мне надо из строки "Select VDC col_3 where col_1 = 200m and col_2 = 300m and col_3 = 400m and col_4 = AA and col_5 = B3B and col_6=4C4" вытащить 200m, 300m, 400m, AA, B3B, 4C4

Пробовал сделать таким образом, но ничего не выходит.

std::string str = "Select VDC col_3 where col_1 = 200m and col_2 = 300m and col_3 = 400m and col_4 = AA and col_5 = B3B and col_6=4C4"
while (str.length() > 0)
{
std::tr1::regex rx("(=\x020*[-+]?[0-9]+[\.\,]?[0-9]+(([eE][-+]?[0-9]+)|((p)|(u)|(m)|(k)|(M)|(G)|(п)|(мк)|(м)|(к)|(М)|(Г)))?)|(=\x020*\w+)");
std::tr1::regex_search(str.c_str(), res, rx);
size_t pos = str.find(res[0].str().c_str());
//printf("%d. Str = %s\n", k, str.c_str());
str = str.substr(pos+res[0].length()).c_str();
printf("Resalt : %s length = %d pos = %d \n ",res[0].str().c_str(),res[0].length(),pos);
if (res[0].length() <= 0)
str.clear();
}

Кроме 200m, 300m, 400m, AA, B3B, 4C4 надо еще вытащить and (может быть or), т.е. 200m, 300m, 400m, AA, B3B, 4C4 , and, or
...
Рейтинг: 0 / 0
04.07.2016, 23:41
    #39267677
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Парсинг строки с++
Я не знаю зачем тебе это нужно. По идее чтобы решить эту задачу тебе нужно проверить что
символ равен знаку равно '=' , разделителю, или любому произвольному символу. Вобщем...
лучшее - враг хорошего.

Почитай до кучи интересную статью на хабре https://habrahabr.ru/post/175375/
...
Рейтинг: 0 / 0
05.07.2016, 00:26
    #39267682
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Парсинг строки с++
Serega325,

вряд ли тебе regex::search нужно, а не match.
...
Рейтинг: 0 / 0
20.07.2016, 03:40
    #39276762
Пётр Седов
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Парсинг строки с++
Serega325, попробуйте так:
Код: plaintext
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.
34.
35.
36.
37.
38.
39.
#include <string.h>
#include <stdio.h>

void parse_query(const char query[]) {
  // берём параметры
  int pos = 0;
  for (;;) {
    // ищем знак равенства, начиная с позиции pos
    const char* sep = strchr(query + pos, '=');
    if (sep == NULL) break;

    // пропускаем знак равенства
    pos = (sep - query) + 1;

    // пропускаем пробелы
    while (query[pos] == ' ') pos++;

    // сканируем параметр
    int param_start = pos;
    while ((query[pos] != '\0') && (query[pos] != ' ')) pos++;
    int param_end = pos;
    const char* param = query + param_start;
    int param_len = param_end - param_start;

    // выводим параметр
    printf("%.*s ", param_len, param); // param не завершается нулём, поэтому надо указать длину
  }

  // берём оператор
  if (strstr(query, " and ") != NULL) printf("and ");
  if (strstr(query, " or ") != NULL) printf("or ");

  printf("\n");
}

int main() {
  parse_query("Select VDC col_3 where col_1 = 200m and col_2 = 300m and col_3 = 400m and col_4 = AA and col_5 = B3B and col_6=4C4");
  return 0;
}
...
Рейтинг: 0 / 0
21.07.2016, 00:04
    #39277409
DeviLooper
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Парсинг строки с++
Serega325надо из строки вытащить 200m, 300m, 400m, AA, B3B, 4C4 , and, or

Код: plaintext
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.
#include <iostream>
#include <string>
#include <regex>

using namespace std;

int main()
{
	string str = "Select VDC col_3 where col_1 = 200m and col_2 = 300m and col_3 = 400m and col_4 = AA and col_5 = B3B and col_6=4C4";
	regex rx = regex("\\s+col_\\d\\s*=\\s*(\\S+)\\s*(and|or)?");
	smatch m;
	int n = 0;

	while(std::regex_search(str, m, rx))
	{
		if(!n && m.size() > 2)
			cout << "Logic: " << m[2] << endl << endl;

		cout << "Col" << n+1 << ": " << m[1] << endl;

		str = m.suffix().str(); // next iteration
		n++;
	}
	return 0;
}



результат:Logic: and

Col1: 200m
Col2: 300m
Col3: 400m
Col4: AA
Col5: B3B
Col6: 4C4
...
Рейтинг: 0 / 0
21.07.2016, 00:07
    #39277410
DeviLooper
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Парсинг строки с++
Можно в принципе и имена вытащить, если вдруг они идут не по порядку
...
Рейтинг: 0 / 0
21.07.2016, 00:16
    #39277411
DeviLooper
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Парсинг строки с++
DeviLooperМожно в принципе и имена вытащить, если вдруг они идут не по порядку
Вот так будет правильнее:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
	regex rx = regex("\\s+(col_\\d)\\s*=\\s*(\\S+)\\s*(and|or)?");

	while(std::regex_search(str, m, rx))
	{
		if(!n && m.size() > 3)
			cout << "Logic: " << m[3] << endl << endl;

		cout << m[1] << ": " << m[2] << endl;

		str = m.suffix().str(); // next iteration
		n++;
	}
...
Рейтинг: 0 / 0
22.07.2016, 15:17
    #39278747
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Парсинг строки с++
Все равно плохо. Постановка простая. А комплексность инструментов которые вы
вовлекаете - избыточна. Я-бы упрощал до тех пор пока проходят модульные тесты.
А если вы считаете что вы покрыли все случаи - тогода Хахаха. Грамматика
SELECT более сложна даже чем данная регулярка.
...
Рейтинг: 0 / 0
22.07.2016, 15:47
    #39278783
Изопропил
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Парсинг строки с++
регулярные выражения не годятся для КС-грамматик.
...
Рейтинг: 0 / 0
22.07.2016, 16:59
    #39278878
DeviLooper
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Парсинг строки с++
maytonА если вы считаете что вы покрыли все случаи - тогода Хахаха. Грамматика
SELECT более сложна даже чем данная регулярка.
Ну топик стартер поставил конкретную задачу. А фантазировать как может быть, а как нет в условия не входило.
...
Рейтинг: 0 / 0
22.07.2016, 17:05
    #39278881
Изопропил
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Парсинг строки с++
Serega325Кроме 200m, 300m, 400m, AA, B3B, 4C4 надо еще вытащить and (может быть or), т.е. 200m, 300m, 400m, AA, B3B, 4C4 , and, or
DeviLooperНу топик стартер поставил конкретную задачу. А фантазировать как может быть, а как нет в условия не входило.

наблюдаю в постановке задачи необходимость разбора логического выражения
...
Рейтинг: 0 / 0
22.07.2016, 17:16
    #39278889
DeviLooper
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Парсинг строки с++
Изопропил,
но он не говорл, что ему нужен универсальный парсер sql запроса
...
Рейтинг: 0 / 0
22.07.2016, 17:17
    #39278890
DeviLooper
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Парсинг строки с++
а логику я вытащил
...
Рейтинг: 0 / 0
22.07.2016, 17:26
    #39278902
Изопропил
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Парсинг строки с++
DeviLooperИзопропил,
но он не говорл, что ему нужен универсальный парсер sql запроса
да, только выражение распарсить
...
Рейтинг: 0 / 0
22.07.2016, 17:30
    #39278911
DeviLooper
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Парсинг строки с++
Изопропил,
может он сам за себя скажет что ему надо ? Хотя, судя по всему, ему уже ничего не надо
...
Рейтинг: 0 / 0
22.07.2016, 17:32
    #39278914
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Парсинг строки с++
Лабу он сдал. И бухает себе. Тащемта топик можно закрыть за бесполезностью.
...
Рейтинг: 0 / 0
28.07.2016, 17:20
    #39282097
Serega325
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Парсинг строки с++
maytonЛабу он сдал. И бухает себе. Тащемта топик можно закрыть за бесполезностью.
Не бухаю, а ищу пути решения. Вот нашел в гугле код, функция check рекурсивно проходит по строке, ищет && или ||, потом делит строку на две части и снова вызывается check и т.д. Когда все разделители (&& и ||) прошли, идет сравнения выражений (col_4=AA)
Код: plaintext
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.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
/*********************************/
//................................
int check(string str, int j)
{
    string s=delete_spaces(str);
 
    if (s.size()==1 && s=="0")
        return 0;
    if (s.size()==1 && s=="1")
        return 1;
    int q=0;
	int ret = s.size()-1;
 
    string s1, s2;
   
    for (int i=s.size()-1; i>=0; --i)
    {

        if(i ==15)
		{
		}
        if (i==0 && s[i]=='(' && q==1)
        {
            s.assign(s, 1, s.size()-2);
            i=s.size()-1;
            q=0;
        }

        if (s[i]==')')
            q+=1;
        if (s[i]=='(')
            q-=1;
 
        if (q==0 && s[i]=='|')
        {
                s1.assign(s, 0, i);
                s2.assign(s, i+1, s.size()-i-1);
                return check(s1,j)||check(s2,j);
        }
        if (q==0 && s[i]=='&')
        {
                s1.assign(s, 0, i);
                s2.assign(s, i+1, s.size()-i-1);
                return check(s1,j)&&check(s2,j);
        }
		if(q==0 && i==0)
		{
			int k = 0;
			lst.DeletedList(); 
			std::regex words_regex("(col_[1-9][0-9]*)|((<[=]?)|(>[=]?)|([!]?=))|([-+]?[0-9]+[\.\,]?[0-9]*)");
			auto words_begin = std::sregex_iterator(str.begin(), str.end(), words_regex);
			auto words_end = std::sregex_iterator();			
			for (std::sregex_iterator i = words_begin; i != words_end; ++i) 
			{
				std::smatch match = *i;
				std::string match_str = match.str();
				lst.putEnd(match_str); //Добавляю в список найденный col_n
				k++;
			}
			return TryParse(j); // Сравниваю два выражения (col_n   =[>,<,=,!= и т.д.]    9), если истина, то вернёт 1 иначе 0
		}
    }
}


Но этот алгоритм работает медленно когда большой массив и сложный select запрос, например
Код: plsql
1.
Select VDC col_3 where ((col_3>col_4) & (col_2_>col_1)) | ((col_1>1) & (col_2=9))


", также вместо and, or надо писать &&,|| и выражения между логическими операциями должны быть в скобках.
Модератор: Оформляй сорцы
...
Рейтинг: 0 / 0
28.07.2016, 17:29
    #39282103
Serega325
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Парсинг строки с++
ИзопропилDeviLooperИзопропил,
но он не говорл, что ему нужен универсальный парсер sql запроса
да, только выражение распарсить
Нужно сделать select запрос к массиву, т.е. в программу приходит массив

char megamass[][20][20] = {
{ { "1" },{ "3" },{ "200" },{ "20" } },
{ { "30" },{ "9" },{ "300" },{ "30" } },
{ { "3" },{ "500" },{ "4000" },{ "40" } },
{ { "1" },{ "3" },{ "200" },{ "20" } },
{ { "30" },{ "9" },{ "300" },{ "30" } },
{ { "3000" },{ "500" },{ "4000" },{ "40" } }
};
Пользователь пишет запрос Select VDC col_3 where ((col_3>col_4) and (col_2_>col_1)) or ((col_1>20) and (col_2=9))
После чего из массива надо получить
{ { "30" },{ "9" },{ "300" },{ "30" } },
{ { "30" },{ "9" },{ "300" },{ "30" } },
{ { "3" },{ "500" },{ "4000" },{ "40" } }
...
Рейтинг: 0 / 0
Форумы / C++ [игнор отключен] [закрыт для гостей] / Парсинг строки с++ / 19 сообщений из 19, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]