Избегайте пустых элементов в совпадении, когда необязательные подстроки отсутствуют - PullRequest
0 голосов
/ 30 апреля 2019

Я пытаюсь создать регулярное выражение, соответствующее строкам, возвращаемым терминальной командой diff.

Эти строки начинаются с десятичного числа, могут иметь подстроку, состоящую из запятой и числа, затем обязательный символ (a, c, d) другого обязательного десятичного числа, за которым следует другая необязательная группа, как предыдущий.

Примеры:

27a27
27a27,30
28c28
28,30c29,31
1d1
1,10d1

Я пытаюсь извлечь все группы отдельно, но необязательные без ,.

Я делаю это в C ++:

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

int main(int argc, char* argv[])
{

  string t = "47a46";
  std::string result;
  std::regex re2("(\\d+)(?:,(\\d+))?([acd])(\\d+)(?:,(\\d+))?");
  std::smatch match;
  std::regex_search(t, match, re2);
  cout<<match.size()<<endl;
  cout<<match.str(0)<<endl;

  if (std::regex_search(t, match, re2))
  {
      for (int i=1; i<match.size(); i++)
      {
          result = match.str(i);
          cout<<i<<":"<<result<< " ";
      }
      cout<<endl;
  }

  return 0;
}

Строковая переменная t - это строка, которой я хочу манипулировать. Мое регулярное выражение

(\\d+)(?:,(\\d+))?([acd])(\\d+)(?:,(\\d+))?

работает, но со строками, которые не имеют необязательных подгрупп (например, 47a46, переменная match будет содержать пустые элементы в соответствующей позиции ожидаемых подстрок.

Например, в программе выше элементы match (с предшествующим их индексом):

1:47 2: 3:a 4:46 5: 

Элементы в позициях 2 и 5 соответствуют необязательной подстроке, которой в данном случае нет, поэтому я бы хотел match, чтобы избежать их получения, чтобы это было:

1:47 2:a 3:46 

Как я могу это сделать?

1 Ответ

1 голос
/ 30 апреля 2019

Я думаю, что лучший RE для вас будет таким:

std::regex re2(R"((\d+)(?:,\d+)?([a-z])(\d+)(?:,\d+)?)");

- таким образом он должен соответствовать всем необходимым группам (но необязательно)

выход:

4
47a46
1:47 2:a 3:46 

Примечание: строка аргумента re2 дана в нотации c ++ 11.

РЕДАКТИРОВАТЬ: немного упрощен RE

...