Невозможно получить результаты сопоставления с регулярным выражением — MFC / Stack Overflow

Я читаю HTML-страницу и пытаюсь извлечь из нее определенную строку.

У меня есть следующий код:

    std::string str = test.GetString(); // someString ( the string i have checked it, it's basically an html page )
std::smatch match;
std::regex re("0x(\\d|[A-Z]).*0000"); // the pattern I'm searching for
if (std::regex_search(str, match, re)){
test = "found"; // found gets printed
}
TRACE("%s\n",match[0]); // this outputs some garbage like this '˜ò'

Я хочу напечатать / сохранить результат найденного совпадения, но вместо этого получаю мусор.

Отказ от ответственности: я новичок в C ++ регулярных выражений. Я мог бы сделать основную ошибку

3

Решение

std::smatch match;
...
TRACE("%s\n",match[0]); // this outputs some garbage like this '˜ò'

%s спецификатор типа в TRACE макрос ожидает необработанный указатель строки C (char* в сборках ANSI / MBCS; wchar_t* в сборках Unicode — я предполагаю, что вы делаете сборку ANSI / MBCS здесь.).

Но match[0] является не необработанный указатель строки C

Таким образом, у вас есть несоответствие между тем, что вы обещали TRACE с помощью %s (то есть необработанная строка C char* указатель) и какой ты на самом деле переходя к нему (т.е. match[0]).

В соответствии с некоторая онлайн документация, std::smatch это специализация std::match_results шаблон, в частности:

smatch --> match_results<string::const_iterator>

smatch::operator[] (который вы вызываете в своем коде как match[0]) возвращает ссылку на другой объект, который является std::sub_match,
это std::sub_match учебный класс представляет пару итераторов, обозначающих последовательности совпадающих символов.

Так ты многообещающий в TRACE передать необработанный указатель на строку C (через %s спецификатор типа), но вы фактически передаете совершенно другая вещь, то есть ссылка на std::sub_match объект (через ваш match[0] код): неудивительно, что печатный текст не имеет смысла.

Что вам нужно сделать, это получить указатель строки C из match[0] выражение.

Для этого вы можете вызвать std::sub_match«s str() метод. Это возвращает std::string объект.

Тем не менее, это std::string объект не именно то, что %s ожидает: на самом деле, %s представляет необработанный указатель на строку C (например, const char*), не std::string пример.

Итак, последний шаг — извлечь этот необработанный указатель строки C из std::string объект, и это делается путем вызова std::string::c_str() метод.

Подводя итог этих логических шагов:

std::smatch match;
...
match[0]               --> reference to std::sub_match object
match[0].str()         --> std::string object
match[0].str().c_str() --> raw C string pointer (const char*)

Так что ваши TRACE Заявление можно записать в виде:

TRACE("%s\n", match[0].str().c_str());
3

Другие решения

Проблема здесь в том, что match[0] возвращает объект типа sub_match, который просто пара итераторов. Если этот первый аргумент макроса TRACE является спецификатором формата в стиле C, преобразуйте sub_match объект в строку C, как это:

TRACE("%s\n", std::string(match[0]).c_str());

То есть использовать sub_match«s operator string() чтобы получить (временный) строковый объект C ++, затем вызовите его функцию-член c_str (), чтобы получить (временный) строковый объект C.

2

По вопросам рекламы [email protected]