![](/img/trans.png)
[英]Iterator invalidation by `std::string::begin()`/`std::string::end()`?
[英]std::regex, to match begin/end of string
在 JS 正則表達式中,符號^
和$
指定字符串的開始和結束。 並且只有使用/m
修飾符(多行模式),它們才匹配行首和行尾- CR/LF 之前和之后的位置。
但是在std::regex /ECMAscript 模式中,符號^
和$
總是匹配行首和行尾。
std::regex 中是否有任何方法來定義字符串匹配點的開始和結束? 換句話說:支持 JavaScript 多行模式......
默認情況下,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_eol
std::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; 博士
^
和$
已匹配開始和行尾std::regex_constants::multiline
選項^
匹配,將字符串的結尾與$
匹配,而無法重新定義其行為。 在除 MSVC 和 C++17 之前的所有std::regex
實現中, ^
和$
匹配string 的開頭和結尾,而不是一行。 請參閱此演示,該演示在^\\d+$
正則表達式中在"1\\n2\\n3"
找不到任何匹配項。 當您添加交替(見下文)時,有 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';
}
會輸出
Match value: 1 at Position 0
Match value: 2 at Position 2
Match value: 3 at Position 4
適用於 C++ 編譯器的解決方法
std::regex
沒有通用選項可以使錨點在所有編譯器中匹配行的開始/結束。 您需要交替模擬它:
^ -> (^|\n)
$ -> (?=\n|$)
請注意, $
可以用(?=\\n|$)
完全“模擬”(您可以在其中添加更多行終止符或符號序列,例如(?=\\r?\\n|\\r|$)
),但使用^
,您無法找到 100% 的解決方法。
由於沒有后視支持,您可能需要調整正則表達式模式的其他部分,因為(^|\\n)
比使用后視支持更頻繁地使用捕獲組。
以下代碼段匹配以 [az] 開頭的電子郵件地址,后跟 0 或 1 個點,然后是 0 個或多個 az 字母,然后以“@gmail.com”結尾。 我測試了它。
string reg = "^[a-z]+\\.*[a-z]*@gmail\\.com$";
regex reg1(reg, regex_constants::icase);
reg1(regex_str, regex_constants::icase);
string email;
cin>>email;
if (regex_search(email, reg1))
您可以使用 Javascript 正則表達式^(?<!(.|\\n)])
模擬 Perl/Python/PCRE \\A
,它在字符串的開頭匹配,但在換行符之后不匹配,翻譯為英語為“匹配開頭沒有前導字符的行”。
您可以使用(?!(.|\\n))$
模擬 Perl/Python/PCRE \\z
,它僅在字符串末尾匹配。 要獲得\\Z
的效果,它僅在字符串結尾匹配但允許在該字符串結尾之前有一個換行符,只需添加一個可選的換行符: \\n?(?!(.|\\n))$
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.