Regex in C++ with back-references and conditionals

Viewed 95

I am trying to match words with optional curly brackets around them. I.e. something like "{word}" or "word".

I want to implement it using conditional expressions.

({)?(word)(?(1)?}|)

where:
({)?      optional 1st group
(word)    mandatory word
(?(1)}|) if-then-else condition, if the first group was found, it matches the same group again

I am not sure about the right syntax for back-references and if-then-else condition in C++.

What I got so far:

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


int
main()
{
  std::regex re("(\\{)?(word)(\\?(\\1)\\}|)");


  // Possible options
  std::vector<std::string> toMatch = {
    "{word}",
    "{word",
    "word"
    }; 

  for (int i = 0; i < toMatch.size(); ++i)
  {
    std::smatch ss;
    std::regex_match(toMatch[i], ss, re);

    std::cout << i << " : " << ss.size() << std::endl;

    for (int j = 0; j < ss.size(); ++j)
    {
        std::cout << "group >   '" << ss[j] << "'" << std::endl;
    }
  }

  return 0;
}

Output:

0 : 0
1 : 5
group >   '{word'
group >   '{'
group >   'word'
group >   ''
group >   ''
2 : 5
group >   'word'
group >   ''
group >   'word'
group >   ''
group >   ''

The first string was not matched at all, the second string matched as it lacks trailing bracket. It seems that conditional and back-referencing mechanisms do not work here.

1 Answers

The default ECMAScript regex flavor used by std::regex (and all other, mostly, POSIX flavors) do not support the conditional construct.

The pattern you have in your code snippet will work in Boost. Judging by your examples, your regex should look like (\{)?(word)(?(1)\}|).

Related