我有以下代碼從一個任意格式的文件解析一束的部件編號(產品的部件的基本序列號)的。如何使用std :: regex_search查找所有出現的模式?
auto buildPartNumberRegexString(bool preFlash) -> std::string
{
std::ostringstream patternBuilder;
// The original, raw literal as tested on https://regex101.com/ is:
//
// @@PART_NUMBER_POST_FLASH\<\s*(\S+)\s*\,\s*(\d+)\s*\>@@
//
// In C++, each backslash needs to be doubled. Alternatively, we could use raw string literals (R"\w").
patternBuilder << "@@PART_NUMBER_" << (preFlash ? "PRE" : "POST")
<< "_FLASH\\<\\s*(\\S+)\\s*\\,\\s*(\\d+)\\s*\\>@@";
return patternBuilder.str();
}
auto parsePartNumberAddresses(const std::string& templateFileContent, bool preFlash) -> ParamAddressContainer
{
const std::regex regEx(buildPartNumberRegexString(preFlash));
std::smatch match;
if (std::regex_search(templateFileContent, match, regEx))
{
assert(match.size() > 1);
const std::size_t capturedGroups = match.size() - 1;
assert(capturedGroups % 2 == 0);
const std::size_t partNumberAddressesFound = capturedGroups/2;
ParamAddressContainer results;
results.reserve(partNumberAddressesFound);
std::cerr << "DEBUG: capturedGroups = " << capturedGroups << ", partNumberAddressesFound = " << partNumberAddressesFound
<< "\n";
for (std::size_t i = 0; i < partNumberAddressesFound; ++i)
{
const std::size_t paramIdMatchIndex = i * 2 + 1;
const std::string paramIdString = match.str(paramIdMatchIndex);
const std::string paramIndexString = match.str(paramIdMatchIndex + 1);
results.emplace_back(util::string_funcs::fromString<ParamId_t> (paramIdString),
util::string_funcs::fromString<ParamIndex_t> (paramIndexString));
}
std::cerr << "DEBUG: Going to read the following part numbers (" << (preFlash ? "pre" : "post") << "-flash):\n\n";
for (const auto& paramAddress : results)
{
std::cerr << "\t" << std::hex << std::noshowbase << paramAddress.paramId << std::dec << "<" << paramAddress.paramIndex
<< ">\n";
}
return results;
}
return ParamAddressContainer();
}
我寫了「美化」正則表達式(即沒有逃脫實際反斜槓需要雙反斜線)在buildPartNumberRegexString功能的註釋。
,我使用這個正則表達式可能是這樣的一個樣本文件:
Component alpha;@@PART_NUMBER_POST_FLASH<F12C,0>@@
Component beta;@@PART_NUMBER_POST_FLASH<F12C,1>@@
我測試過我正則表達式,使用相同的樣本文件,在https://regex101.com/和它的作品,正是因爲它應該,匹配兩個事件並提取所需的匹配組。問題是,當我嘗試通過std :: regex做同樣的事情時,它只找到第一個匹配項。現在https://regex101.com/我不得不啓用摹修改(全球,所有的比賽,不要第一場比賽返回)的正則表達式查找所有的比賽。我假設(希望),類似的標誌是可用於std::regex_search
,但可用的標誌(http://en.cppreference.com/w/cpp/regex/match_flag_type)的說明似乎並沒有列出任何符合我的要求。當然,必須有一種方法來查找一個以上的模式,對嗎?有人有想法嗎?
std :: regex_iterator上的cppreference.com頁面顯示瞭如何獲得所有匹配..猜我應該添加一個註釋到std :: regex_search – Cubbi
Cubbi,我不確定它確實如此。關於cppreference調用的示例在數組中的所有字符串上重複使用regex_search。在我的情況下,我沒有一個字符串數組,我只有一個字符串。我知道我可以將樣本文件分成幾行,但正如我所說的,輸入可以任意格式化,並且不能保證每行總是有一個匹配。單行可能有2個或更多。 – antred
是的,這並不明顯。添加了一個筆記。 – Cubbi