TL;DR
- MSVC: the
^
and $
already match start and end of lines
- C++17: use
std::regex_constants::multiline
option
- Other compilers only match start of string with
^
and end of string with $
with no a possibility to redefine their behavior.
In all std::regex
implementations other than MSVC and before C++17, the ^
and $
match beginning and end of the string, not a line. See this demo that does not find any match in "1\n2\n3"
with ^\d+$
regex. When you add alternations (see below), there are 3 matches.
However, in MSVC and C++17, the ^
and $
may match start/end of the line.
C++17
Use the std::regex_constants::multiline
option.
MSVC compiler
In a C++ project in Visual Studio, the following
std::regex r("^\\d+$");
std::string st("1\n2\n3");
for (std::sregex_iterator i = std::sregex_iterator(st.begin(), st.end(), r);
i != std::sregex_iterator();
++i)
{
std::smatch m = *i;
std::cout << "Match value: " << m.str() << " at Position " << m.position() << '\n';
}
will output
Match value: 1 at Position 0
Match value: 2 at Position 2
Match value: 3 at Position 4
Workarounds that work across C++ compilers
There is no universal option in std::regex
to make the anchors match start/end of the line across all compilers. You need to emulate it with alternations:
^ -> (^|\n)
$ -> (?=\n|$)
Note that $
can be "emulated" fully with (?=\n|$)
(where you may add more line terminator symbols or symbol sequences, like (?=\r?\n|\r|$)
), but with ^
, you cannot find a 100% workaround.
Since there is no lookbehind support, you might have to adjust other parts of your regex pattern because of (^|\n)
like using capturing groups more often than you could with a lookbehind support.