默认情况下,EcmaScript的模式已经把^既开始输入的,并且开始的行,并$为最终的输入都和结束线.没有办法让它们仅匹配开头或结尾输入,但可以使它们仅匹配开头或结尾:
调用std::regex_match时std::regex_search,或者std::regex_replace,有一个std::regex_constants::match_flag_type默认类型的参数std::regex_constants::match_default.
^仅匹配行首,请指定std::regex_constants::match_not_bol$仅匹配行尾,请指定std::regex_constants::match_not_eolstd::regex_constants::match_not_bol | std::regex_constants::match_not_eol)^,无论是否存在std::regex_constants::match_not_bol指定std::regex_constants::match_continuous这在cppreference.com上的ECMAScript语法文档中有很好的解释,我强烈推荐cplusplus.com.
警告:我已经使用MSVC,Clang + libc ++和Clang + libstdc ++进行了测试,目前只有MSVC具有正确的行为.
TL; DR
^和$已经匹配的行的开头和结尾std::regex_constants::multiline选项^和结尾匹配$,无法重新定义其行为。在std::regex除MSVC之外且在C ++ 17之前的所有实现中,^and $匹配字符串的开头和结尾,而不是一行。请参见此演示,该演示找不到"1\n2\n3"与^\d+$regex 匹配的内容。当您添加交替(见下文)时,有3个匹配项。
然而,在MSVC和C ++ 17中,^并且$可以匹配开始/所述的端线。
C ++ 17
使用该std::regex_constants::multiline选项。
MSVC编译器
在Visual Studio中的一个C ++项目中,以下内容
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';
}
Run Code Online (Sandbox Code Playgroud)
将输出
Match value: 1 at Position 0
Match value: 2 at Position 2
Match value: 3 at Position 4
Run Code Online (Sandbox Code Playgroud)
跨C ++编译器的变通办法
没有通用选项std::regex可以使锚在所有编译器中都与行的开头/结尾匹配。您需要以交替方式模仿它:
^ -> (^|\n)
$ -> (?=\n|$)
Run Code Online (Sandbox Code Playgroud)
请注意,$可以使用完全“模拟” (?=\n|$)(您可以在其中添加更多的行终止符或符号序列,例如(?=\r?\n|\r|$)),但是使用^,则找不到100%的解决方法。
由于没有后向支持,因此您可能需要调整正则表达式模式的其他部分,因为(^|\n)比起向后支持,您更喜欢使用捕获组。