正则表达式搜索重叠匹配C ++ 11

时间:2019-01-15 03:40:39

标签: regex c++11

我应该使用什么正则表达式来搜索所有匹配的内容:

  • 以55或66开头
  • 后接[0-9a-fA-F](十六进制数字)范围内的至少8个字符
  • \r结尾(<回车)

示例字符串:0205065509085503400066 / r09 \ r

我的预期结果:

5509085503400066\r
5503400066\r

我当前的结果:

5509085503400066\r

使用

 (?:55|66)[0-9a-fA-F]{8,}\r

您可以说,这只会找到第一个结果,而不是第二个结果。

修改说明

我使用正则表达式搜索字符串。它将选择消息以进行进一步解析。目标字符串可以在字符串中的任何位置开始。目标字符串仅在包含十六进制(HEX)数字并以回车结尾时才有效。

[开始] [信息部分至少8个字符] [结束符号和字符返回]

我正在使用c ++ 11中的std :: regex库,其标志为 ECMAScript

修改

我创建了一个替代解决方案,可以给我预期的结果。但这不是纯正则表达式。

#include <iostream>
#include <string>
#include <regex>
int main()
{
// repeated search (see also 
std::regex_iterator)
std::string log("0055\r0655036608090705\r");
std::regex r("(?:55|66)[0-9a-fA-F]{8,}\r");
std::smatch sm;
while(regex_search(log, sm, r))
{
    std::cout << sm.str() << '\n';
    log = sm.str();
    log += sm.suffix();
    log[0] = 'a' ;
}
}

**编辑:基于评论的正则表达式解决方案**

#include <iostream>
#include <string>
#include <regex>

int main()
{
// repeated search (see also 
std::regex_iterator)
std::string s("0055\r06550003665508090705\r0970");
std::regex r("(?=((?:55|66)[0-9a-fA-F]{8,}\r))");
auto words_begin = 
    std::sregex_iterator(s.begin(), s.end(), r);
auto words_end =  std::sregex_iterator();

std::cout << "Found " 
          << std::distance(words_begin, words_end) 
          << " words:\n";

for (std::sregex_iterator i = words_begin; i != words_end; ++i) {
    std::smatch match = *i;                                                 
    std::string match_str = s.substr(match.position(1), match.length(1) - 1); //-1 cr
    std::cout << match_str << " =" << match.position(1) << '\n';
}  
} 

1 个答案:

答案 0 :(得分:2)

您实际上正在寻找重叠的匹配项。可以使用正则表达式lookahead这样实现:

(?=((?:55|66)[0-9a-fA-F]{8,}\/r))

您将在组1中找到有问题的匹配项。但是,完全匹配项为空。

Regex Demo (仅出于演示目的,使用/r代替回车)

Sample Code

#include <iostream>
#include <string>
#include <regex>
using namespace std;

int main() {
    std::string subject("0055\r06550003665508090705\r0970");
    try {
      std::regex re("(?=((?:55|66)[0-9a-fA-F]{8,}\r))");
      std::sregex_iterator next(subject.begin(), subject.end(), re);
      std::sregex_iterator end;
      while (next != end) {
        std::smatch match = *next;
        std::cout << match.str(1) << "\n";
        next++;
      } 
    } catch (std::regex_error& e) {
      // Syntax error in the regular expression
    }
    return 0;
}

另请参阅:Regex-Info: C++ Regular Expressions with std::regex