Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Поиск с регулярным выражением


Автор: supercelt 17.3.2023, 23:21
Добрый вечер! Пишу на СИ. Суть вот в чём. Есть строка

Код

gsm_buffer[255] = "Какие-то любые символы \r\n+CME ERROR:58\r\n какие-то любые символы";


Мне надо найти подстроку \r\n+CME ERROR:58\r\n. Но вместо 58 может быть любое число. Понятно что можно применить регулярки. Но возникла другая проблема. Есть библиотека PCRE2. Я ее скачал. Собрал с помощью CMAKE. Получились на выходе фалы, среди которых есть pcre2.h. Я его скопировал в MINGW\include. Но при компиляции вылетают ошибки, которые я мало понимаю что означают. Я не силён именно в сборках и внедрении библиотек. А мануал на английском по большей части и рассчитан на то что человек уже шарит хоть что-то в сборках. У меня такое ощущение что после сборки в CMAKE это всё надо еще как-то инсталлировать, а не просто скопировать заголовочный файл...
Кстати при компиляции проекта вылетают следующие ошибки:
Код

C:\Users\SUPERC~1\AppData\Local\Temp\ccLXBu3W.o:test.c:(.text+0x60): undefined reference to `_imp__pcre2_compile_8'
C:\Users\SUPERC~1\AppData\Local\Temp\ccLXBu3W.o:test.c:(.text+0x92): undefined reference to `_imp__pcre2_get_error_message_8'
C:\Users\SUPERC~1\AppData\Local\Temp\ccLXBu3W.o:test.c:(.text+0xd6): undefined reference to `_imp__pcre2_match_data_create_from_pattern_8'
C:\Users\SUPERC~1\AppData\Local\Temp\ccLXBu3W.o:test.c:(.text+0x131): undefined reference to `_imp__pcre2_match_8'
C:\Users\SUPERC~1\AppData\Local\Temp\ccLXBu3W.o:test.c:(.text+0x185): undefined reference to `_imp__pcre2_code_free_8'
C:\Users\SUPERC~1\AppData\Local\Temp\ccLXBu3W.o:test.c:(.text+0x1ac): undefined reference to `_imp__pcre2_get_ovector_pointer_8'
C:\Users\SUPERC~1\AppData\Local\Temp\ccLXBu3W.o:test.c:(.text+0x29b): undefined reference to `_imp__pcre2_match_data_free_8'
C:\Users\SUPERC~1\AppData\Local\Temp\ccLXBu3W.o:test.c:(.text+0x2ac): undefined reference to `_imp__pcre2_code_free_8'
collect2.exe: error: ld returned 1 exit status


Мой код полностью:
Код

#define PCRE2_CODE_UNIT_WIDTH 8
#include <pcre2.h>
#include <stdio.h>
#include <string.h>
 
int main(void) {
    PCRE2_SPTR pattern = (PCRE2_SPTR)"CME ERROR:[0-9]+\r";
    PCRE2_SPTR subject = (PCRE2_SPTR)"CME ERROR:1658\r";
    pcre2_code* re;
    int errornumber;
    PCRE2_SIZE erroroffset;
    
    // pcre2_compile - компилирует шаблон
    re = pcre2_compile(pattern, PCRE2_ZERO_TERMINATED, 0, &errornumber, &erroroffset, NULL);
    if (re == NULL) {
        PCRE2_UCHAR buffer[256];
        pcre2_get_error_message(errornumber, buffer, sizeof(buffer));
        printf("PCRE2 compilation failed at offset %d: %s\n", (int)erroroffset, buffer);
        return 1;
    }
    pcre2_match_data* match_data = pcre2_match_data_create_from_pattern(re, NULL);
    
    // pcre2_match - выполняет сопоставление
    int rc = pcre2_match(re, subject, strlen((char*)subject), 0, 0, match_data, NULL);
    
    // Если свопадения не найдены, то выводим ошибку
    if (rc < 0) {
        switch (rc) {
        case PCRE2_ERROR_NOMATCH: printf("No match\n"); break;
        default: printf("Matching error %d\n", rc); break;
        }
        pcre2_code_free(re);
        return 1;
    }
 
    // Если совпадения найдены, то выводится сообщение "Match succeeded"
    printf("Match succeeded\n");
 
    // pcre2_get_ovector_pointer - извлекает вектор смещения, который содержит
    // начальную и конечную точки любых совпадений, найденных в строке объекта
    PCRE2_SIZE* ovector = pcre2_get_ovector_pointer(match_data);
    PCRE2_SIZE subject_length = strlen((char*)subject);
    for (int i = 0; i < rc; i++) {
        PCRE2_SPTR start_ptr = subject + ovector[2 * i];
        PCRE2_SPTR end_ptr = subject + ovector[2 * i + 1];
        PCRE2_SIZE length = end_ptr - start_ptr;
        printf("%2d: %.*s\n", i, (int)length, start_ptr);
    }
 
    // В конце производится освобождение
    pcre2_match_data_free(match_data);
    pcre2_code_free(re);
 
    return 0;
}


Получается у меня основная проблема как искать с помощью регулярок или другой способ.... и если регулярки - оптимальное решение, то проблема выше - инсталляция библиотеки

Спасибо большое если ответите.

Автор: Oldshelf 18.3.2023, 05:11
Цитата(supercelt @  17.3.2023,  23:21 Найти цитируемый пост)
Я его скопировал в MINGW\include

Там, кажется, ещё надо соответствующие библиотеки скопировать в "MINGW\lib". Типа: "*.a".

Добавлено через 2 минуты и 27 секунд
...и указать их явно в параметрах компоновщика, как, например, указана библиотека "-mwindows".

Автор: supercelt 18.3.2023, 18:35
Там в файлах даже нет таких, с расширением .а 

Автор: Oldshelf 19.3.2023, 06:16
Не уверен, что поможет, но вот обсуждение подключения соответствующей статической библиотеки ("libpcre2-32.a") в проект: https://stackoverflow.com/questions/73631617/pcre2-include-a-static-library-in-c-cmake-project

Автор: supercelt 19.3.2023, 19:31
Цитата(Oldshelf @ 19.3.2023,  06:16)
Не уверен, что поможет, но вот обсуждение подключения соответствующей статической библиотеки ("libpcre2-32.a") в проект: https://stackoverflow.com/questions/73631617/pcre2-include-a-static-library-in-c-cmake-project

Не помогло(

Автор: Oldshelf 20.3.2023, 05:37
Цитата(supercelt @  18.3.2023,  18:35 Найти цитируемый пост)
Там в файлах даже нет таких, с расширением .а 

А есть ли вообще раздел "MINGW\lib"? Если - да, то там среди прочих библиотек есть что-то похожее на "pcre2"?

Автор: YUENHOIFEF 26.3.2023, 07:06
Цитата

Мне надо найти подстроку \r\n+CME ERROR:58\r\n

Это не подстрока, а строка.
Можно сравнивать шаблон с часть строки, а не со всей строкой, с помощью функции: strnstr();
+CME ERROR:58
+CME ERROR
Ищешь подстроку в строке(выделено зеленым), и если совпало - выдергиваешь цифру(то что после : )

Автор: supercelt 26.3.2023, 22:26
Цитата(Oldshelf @  20.3.2023,  05:37 Найти цитируемый пост)
А есть ли вообще раздел "MINGW\lib"? Если - да, то там среди прочих библиотек есть что-то похожее на "pcre2"? 

Конечно же нет

Добавлено через 1 минуту и 28 секунд
Цитата(YUENHOIFEF @  26.3.2023,  07:06 Найти цитируемый пост)
Можно сравнивать шаблон с часть строки, а не со всей строкой, с помощью функции: strnstr();

Не подходит к сожалению, мне надо убедиться что после числа обязательно приняты \r\n. И только после этого дёргать число

Автор: Oldshelf 27.3.2023, 05:02
Цитата(supercelt @  26.3.2023,  22:26 Найти цитируемый пост)
Конечно же нет

Тогда необходимо сначала добавить каким-либо способом эту библиотеку в раздел "lib", например https://packages.msys2.org/base/mingw-w64-pcre2, а потом явно подключить в параметрах компоновщика.

Хотя, кажется, эта библиотека должна появиться где-то после "cmake", вместе с "pcre2.h".

Автор: YUENHOIFEF 27.3.2023, 11:11
supercelt,  И тем не менее эта задача легко решаема без регулярных выражений.
Читаешь текст построчно (если очень надо, пусть концом строки является \r\n, а не просто \n)
Сравниваешь с шаблоном.
Проверяешь - число ли в конце.
Делов-то...
Испоьзовать RegExp в Cи, как-то не так и что-то не то.  smile 
Это мое мнение, не более.


Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)