Я читаю 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 ++ регулярных выражений. Я мог бы сделать основную ошибку
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());
Проблема здесь в том, что 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.