2

Given a multiple line string A;1;\nB;2\nC;3. It's needed to add a ; before those newline characters that are not immediately preceded by ;. So, the result should be A;1;\nB;2;\nC;3 (a single ; is added after 2). I've tried different regexes but without luck (one of them is presented below). I think the lookbehind assertion would do the job, but it isn't supported.

Question: What regex expression can solve this problem? If none, how to solve it using other methods using pure C++ only (I'm using C++20)?

std::string s{ "A;1;\nB;2\nC;3" };
const std::regex re("(?!;)\\n");  // Produces "A;1;;\nB;2;\nC;3" (redundant ";" after "1").
s = std::regex_replace(s, re, ";\n");
ENIAC
  • 813
  • 1
  • 8
  • 19

1 Answers1

1

You can match and capture either a string start position or any character other than a ; char, and then capture a newline char, and replace the matches using backreferences:

#include <iostream>
#include <regex>

int main() {
    std::string s{ "A;1;\nB;2\nC;3" };
    const std::regex re("([^;]|^)(\\n)");  // Produces "A;1;;\nB;2;\nC;3" (redundant ";" after "1").
    s = std::regex_replace(s, re, "$1;$2");
    std::cout << s;
    return 0;
}

See the C++ demo and the regex demo.

Output:

A;1;
B;2;
C;3

Pattern details:

  • ([^;]|^) - Group 1 ($1): either a char other than a semi-colon ([^;]), or (|) a start of the string position (^) (remove |^ if there is no need to match substrings at the start of the string)
  • (\\n) - Group 2 ($2): a newline char.
Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563