16

I am using the following pattern:

(?<=<)(?<!>).*?q.*?(?!<)(?=>)

It uses positive and negative lookahead and lookbehind to match the literal q that is enclosed in matching brackets.

std::regex does not support lookbehind. So what would be a good alternative?

Ardent Coder
  • 3,777
  • 9
  • 27
  • 53
Joey
  • 261
  • 4
  • 14
  • 1
    It is a very weird pattern that won't work if there are several `<...>` substrings in the same line. If you still need this regex, you'd use `<(.*?q.*?)>` and grab `smatch_obj.str(1)`. However, `<([^>q]*q[^>]*)>` will perform better and will be more precise. – Wiktor Stribiżew Apr 19 '17 at 18:15
  • 1
    `boost` supports that – Shakiba Moshiri Apr 19 '17 at 19:14

1 Answers1

5

Note that (?<=<)(?<!>) is equal to (?<=<) (since a < is required immediately to the left of the current location, there cannot be any >) and (?!<)(?=>) is equal to (?=>) (same logic applies here, as > must be immediately to the right, there won't be any <). The first .*? will not match the shortest substring possible, it will literally find its way to the first q that is followed with any 0+ chars up to the first >. So, the pattern is hardly working for you even in the lookbehind-supporting engine.

I'd rather use <([^<>q]*q[^<>]*)> regex with a capturing group and literal consuming < and > symbols at the start/end of the expression:

std::regex r("<([^<>q]*q[^<>]*)>");
std::string s = "<adqsdq<><abc>5<abq>6<qaz> <hjfffffffk>";
for(std::sregex_iterator i = std::sregex_iterator(s.begin(), s.end(), r);
                         i != std::sregex_iterator();
                         ++i)
{
    std::cout << (*i).str(1)  << srd::endl;
}

See the C++ demo

Output: abq and qaz

Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
  • Thanks Wiktor, problem with your regex is that it doesnt take into account the presence of another bracket so for instance`` should not match because there is a left bracket inside a left/right. I hope this makes sense – Joey Apr 19 '17 at 18:41
  • Ok, use `<([^<>q]*q[^<>]*)>`. [Your regex did not account for that](https://regex101.com/r/EbY5ld/1). – Wiktor Stribiżew Apr 19 '17 at 18:42
  • Check the answer now, I have updated it with a regex that does not match the string you provided. – Wiktor Stribiżew Apr 19 '17 at 18:47
  • Perhaps I should post this as another question, but how do you replace captured groups only in C++ RegEx. – Joey Apr 19 '17 at 18:58
  • 1
    No, you do not replace capture groups only, you capture what you need to keep and only match what you need to remove. If you need to replace something specific inside a capture group you need a callback. – Wiktor Stribiżew Apr 19 '17 at 19:14
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/142190/discussion-between-joey-and-wiktor-stribizew). – Joey Apr 20 '17 at 14:09