Поиск регулярных выражений с совпадением с ++ 11 - PullRequest
0 голосов
/ 15 января 2019

Какое выражение регулярного выражения следует использовать для поиска всех совпадений:

  • Начните с 55 или 66
  • , за которыми следуют минимум 8 символов в диапазоне [0-9a-fA-F] (Шестнадцатеричные числа)
  • Заканчивается на \r (возврат каретки)

Пример строки : 0205065509085503400066 / r09 \ r

Мой ожидаемый результат:

5509085503400066\r
5503400066\r

Мой текущий результат:

5509085503400066\r

Использование

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

Как вы можете видеть, он находит только первоерезультат, но не второй.

Редактировать пояснение

Я ищу строку, используя Regex.Он выберет сообщение для дальнейшего разбора.Целевая строка может начинаться где угодно в строке.Целевая строка действительна только в том случае, если она содержит только числа 16 (HEX) и заканчивается возвратом каретки.

[start] [информационная часть минимум 8 символов] [end end-carigge return]

Я использую библиотеку std :: regex в c ++ 11 с флагом 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 голосов
/ 16 января 2019

Вы на самом деле ищете совпадения матчей. Это может быть достигнуто с помощью регулярного выражения lookahead , например:

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

Соответствующие совпадения вы найдете в группе 1. Однако полное совпадение пусто.

Regex Demo (использование /r вместо возврата каретки только для демонстрационных целей)

Пример кода :

#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 ++ с std :: regex

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...