C++ Boost 正则表达式与标准库正则表达式匹配结果

C++ Boost regex vs Standard Library regex match results

难以使 boost 正则表达式匹配结果以与标准库相同的方式出现。这意味着标准库 return 是多行输入中产生多个匹配项的第一个匹配项。

我们的目标是获得最佳性能,因为 运行 此代码对它的影响很大。子字符串调用非常慢,因此是提升处理方式的方法。

此产品是 C++ 11 之前的 C++。我无法升级的老东西。

示例如下:

_模式:[A-Za-z0-9].+\n[ \t]*\n

输入字符串:(换行必不可少)

CLINICAL: Left 2cm Firm Fibrous Lump @12:00.

No prior exams were available for comparison.

There is gynecomastia in both feet.

代码的标准库版本:

ORegExpr::index(const OString &inputStr, size_t* length, size_t start = 0) const {
if (start == O_NPOS)
    return O_NPOS;

std::smatch reMatch;    
std::regex re(_pattern);
std::string inputData = "";
if (start > 0 )
    inputData = inputStr._string.substr(start); 
else
    inputData = inputStr._string;

if(std::regex_search(inputData,reMatch,re))
{
  *length = reMatch.length();
  return reMatch.position(0) + start;   
}
*length = 0;
return O_NPOS;
}

**升级版**

size_t
ORegExpr::index_boost(const OString &inputStr, size_t* length, size_t start = 0) const {
if (start == O_NPOS)
    return O_NPOS;  

boost::regex re(_pattern);

boost::match_results<std::string::const_iterator> what;
boost::match_flag_type flags = boost::match_default;    
std::string::const_iterator s = inputStr.std().begin() + start;    
std::string::const_iterator e = inputStr.std().end();

if(boost::regex_search(s,e,what,re,flags)){
    *length = what.length();        
    return what.position() + start;
}

*length = 0;
return O_NPOS;
}

** 将 boost 替换为 std 以查看使用 interators 是否会有所不同 **

size_t
ORegExpr::index_boostnowstd(const OString &inputStr, size_t* length, size_t start = 0) const {
if (start == O_NPOS)
    return O_NPOS;  

std::regex re(_pattern);

std::match_results<std::string::const_iterator> what;
//boost::match_flag_type flags = boost::match_default;  
std::string::const_iterator s = inputStr.std().begin() + start;    
std::string::const_iterator e = inputStr.std().end();

if(std::regex_search(s,e,what,re)){
    *length = what.length();        
    return what.position() + start;
}

*length = 0;
return O_NPOS;
}

我尝试了所有可能的方法来获得 "array" 的比赛并且只是 return 第一场比赛的长度,但是对于我来说我无法从促进。它将 return 两个匹配项以及它们的总长度,即输入字符串的第一行和第二行。

如果我的解释没有我想象的那么好,我有完整的 POC。

我希望函数的输出为 return a size_t 46,这是输入字符串第一行的长度。标准库会这样做,但 boost 不会。提升的原因是它似乎 运行 比标准库快。

您的正则表达式实际上匹配前两行,而不是单独匹配第一行。

试试这个:

"[^\n]+\n\n"

Live Demo (C++03)

此正则表达式将匹配第一次出现的 "no newline characters followed by two newline characters",它将匹配输出的第一行,长度为 46(包括换行符)


编辑: 从您的评论来看,您似乎坚持使用给定的表达式。

您可以尝试使用 Boost 的 match_flag_type 来改变正则表达式的工作方式。在这种情况下,使用 boost::match_any 到 return 最左边的匹配项。

boost::match_flag_type flags = boost::match_any;

来自 match_any 的文档:

Specifies that if more than one match is possible then any match is an acceptable result: this will still find the leftmost match, but may not find the "best" match at that position. Use this flag if you care about the speed of matching, but don't care what was matched (only whether there is one or not).

Demo #2