簡體   English   中英

std::regex,匹配字符串的開頭/結尾

[英]std::regex, to match begin/end of string

在 JS 正則表達式中,符號^$指定字符串的開始和結束 並且只有使用/m修飾符(多行模式),它們才匹配行首和行尾- CR/LF 之前和之后的位置。

但是在std::regex /ECMAscript 模式中,符號^$總是匹配行首和行尾

std::regex 中是否有任何方法來定義字符串匹配點的開始和結束 換句話說:支持 JavaScript 多行模式......

默認情況下,EcmaScript的模式已款待^既是開始-的輸入開始的行,和$作為最終的線都結束輸入 沒有辦法讓它們匹配開頭或結尾輸入,但可以讓它們匹配開頭或結尾:

當調用std::regex_matchstd::regex_searchstd::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; 博士

  • MSVC:該^$已匹配開始和
  • C++17:使用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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM