正規表示式工具 |
grep |
PowerGREP |
RegexBuddy |
RegexMagic |
一般應用程式 |
EditPad Lite |
EditPad Pro |
語言和函式庫 |
Boost |
Delphi |
GNU (Linux) |
Groovy |
Java |
JavaScript |
.NET |
PCRE (C/C++) |
PCRE2 (C/C++) |
Perl |
PHP |
POSIX |
PowerShell |
Python |
R |
Ruby |
std::regex |
Tcl |
VBScript |
Visual Basic 6 |
wxWidgets |
XML Schema |
Xojo |
XQuery 和 XPath |
XRegExp |
資料庫 |
MySQL |
Oracle |
PostgreSQL |
此網站上的更多資訊 |
簡介 |
正規表示式快速入門 |
正規表示式教學 |
取代字串教學 |
應用程式和語言 |
正規表示式範例 |
正規表示式參考 |
取代字串參考 |
書籍評論 |
可列印 PDF |
關於此網站 |
RSS Feed 和部落格 |
C++11 標準中定義的 C++ 標準函式庫在 <regex> 標頭中提供正規表示式的支援。在 C++11 之前,<regex> 是 C++ 標準函式庫的 TR1 延伸模組的一部分。當此網站提到 std::regex 時,是指包含在 Visual C++ 2008 及更新版本中的 C++ 標準函式庫的 Dinkumware 實作。當目標為 Win64 時,C++Builder XE3 及更新版本也支援此函式庫。在 Visual C++ 2008 中,命名空間是 std::tr1::regex,而不是 std::regex。
C++Builder 10 及更新版本支援 Dinkumware 實作 std::regex,只要將使用傳統 Borland 編譯器的選項停用,即可鎖定 Win32。在 C++Builder XE3 及更新版本中使用傳統 Borland 編譯器時,您可以使用 boost::regex 取代 std::regex。雖然 std::regex 在 TR1 和 C++11 中定義的運算和類別與 boost::regex 幾乎相同,但實際 regex 風格仍有許多重要的差異。最重要的是,Boost 中的 ECMAScript regex 語法新增了許多從 Perl 借用的功能,這些功能並非 ECMAScript 標準的一部分,且未在 Dinkumware 函式庫中實作。
std::regex_constants 中定義了六種不同的正規表示法風格或語法
大多數 C++ 參考都說明 C++11 實作了 ECMA-262v3 和 POSIX 標準中定義的正規表示法。但實際上,C++ 實作是根據這些標準非常鬆散地建立的。語法非常接近。唯一的重大差異是 std::regex 即使在 ECMAScript 模式下也支援 POSIX 類別,且對於哪些字元必須跳脫(例如大括號和右中括號)以及哪些字元不需跳脫(例如字母)有些特別。
但此語法的實際行為有重要的差異。在 std::regex 中,插入符號和美元符號 始終會與內嵌換行符號相符,而在 JavaScript 和 POSIX 中,這是一個選項。與大多數 regex 風格一樣,對非參與群組的反向參照無法相符,而在 JavaScript 中,它們會找到零長度相符。在 JavaScript 中,\d 和 \w 僅限於 ASCII,而 \s 則相符於所有 Unicode 空白。這很奇怪,但所有現代瀏覽器都遵循此規範。在 std::regex 中,使用 char 字串時,所有 簡寫 都僅限於 ASCII。在 Visual C++ 中(但 C++Builder 中沒有),使用 wchar_t 字串時,它們支援 Unicode。在 Visual C++ 中使用 wchar_t 時,POSIX 類別 也會相符於非 ASCII 字元,但並未一致包含所有預期的 Unicode 字元。
實際上,您大多會使用 ECMAScript 語法。它是預設語法,提供的功能遠多於其他語法。每當本網站上的教學課程提到 std::regex 但未提到任何語法時,所寫的內容就適用於 ECMAScript 語法,可能適用於其他語法,也可能不適用。您實際上只會在想要重複使用舊 POSIX 程式碼或 UNIX 指令碼中的現有正規表示法時,才會使用其他語法。
在使用正規表示式之前,您必須建立範本類別 std::basic_regex 的物件。如果您要處理的主題是 char 陣列或 std::string 物件,您可以輕鬆地使用這個範本類別的 std::regex 實例化來執行此動作。如果您要處理的主題是 wchar_t 陣列或 std::wstring 物件,請使用 std::wregex 實例化。
將您的正規表示式作為字串傳遞給建構函式的第一個參數。如果您想要使用 ECMAScript 以外的正規表示式風格,請將適當的常數作為第二個參數傳遞。您可以將這個常數「或」運算 std::regex_constants::icase,以讓正規表示式不區分大小寫。您也可以將它「或」運算 std::regex_constants::nosubs,以將所有擷取群組轉換為非擷取群組,如果您只關心整體正規表示式比對,而且不想要擷取任何擷取群組比對到的文字,這樣可以讓您的正規表示式更有效率。
呼叫 std::regex_search(),並將您的主題字串作為第一個參數,將正規表示式物件作為第二個參數,以檢查您的正規表示式是否可以比對字串的任何部分。如果您想要檢查您的正規表示式是否可以比對整個主題字串,請呼叫 std::regex_match(),並使用相同的參數。由於 std::regex 缺乏專門在字串開頭和結尾比對的錨定,因此您在使用正規表示式驗證使用者輸入時,必須呼叫 regex_match()。
regex_search() 和 regex_match() 都只會傳回 true 或 false。若要取得 regex_search() 比對到的字串部分,或是在使用任一函式時取得擷取群組比對到的字串部分,您需要將範本類別 std::match_results 的物件作為第二個參數傳遞。正規表示式物件接著會成為第三個參數。使用下列四個範本實例化之一的預設建構函式來建立這個物件
當函式呼叫傳回 true 時,您可以呼叫 match_results 物件的 str()、position() 和 length() 成員函式,以取得配對的文字,或相對於主旨字串的配對開始位置及其長度。呼叫這些成員函式時不帶參數或以 0 為參數,以取得整體 regex 配對。呼叫時傳遞 1 或更大的數字,以取得特定擷取群組的配對。size() 成員函式指出擷取群組的數量,加上整體配對的 1。因此,您可以傳遞一個值,範圍為 size()-1,至其他三個成員函式。
將所有內容組合在一起,我們可以像這樣取得第一個擷取群組配對的文字
std::string subject("Name: John Doe"); std::string result; try { std::regex re("Name: (.*)"); std::smatch match; if (std::regex_search(subject, match, re) && match.size() > 1) { result = match.str(1); } else { result = std::string(""); } } catch (std::regex_error& e) { // Syntax error in the regular expression }
若要尋找字串中的所有 regex 配對,您需要使用反覆運算器。使用這四個範本實例化之一,建立範本類別 std::regex_iterator 的物件
呼叫建構函式並使用三個參數來建立一個物件:指出搜尋開始位置的字串反覆運算器、指出搜尋結束位置的字串反覆運算器,以及 regex 物件。如果找到任何配對,物件在建立時將包含第一個配對。使用預設建構函式建立另一個反覆運算器物件,以取得序列結束反覆運算器。您可以將第一個物件與第二個物件進行比較,以判斷是否有任何進一步的配對。只要第一個物件不等於第二個物件,您就可以取消第一個物件的參考,以取得 match_results 物件。
std::string subject("This is a test"); try { std::regex re("\\w+"); std::sregex_iterator next(subject.begin(), subject.end(), re); std::sregex_iterator end; while (next != end) { std::smatch match = *next; std::cout << match.str() << "\n"; next++; } } catch (std::regex_error& e) { // Syntax error in the regular expression }
若要取代字串中的所有配對,請呼叫 std::regex_replace(),並將您的主旨字串作為第一個參數、regex 物件作為第二個參數,以及包含取代文字的字串作為第三個參數。此函式會傳回一個套用取代結果的新字串。
替換字串的語法與 JavaScript 類似,但並非完全相同。無論您使用哪種 regex 語法或文法,都會使用相同的替換字串語法。您可以使用 $& 或 $0 來插入整個 regex 比對,並使用 $1 到 $9 來插入前九個擷取群組比對到的文字。沒有辦法插入第 10 個或更高群組比對到的文字。$10 和更高群組永遠會被替換為空白,而 $9 和更低群組如果 regex 中的擷取群組少於要求的數字,也會被替換為空白。$`(美元符號反引號)是比對左側的字串部分,而 $'(美元符號單引號)是比對右側的字串部分。
| 快速入門 | 教學 | 工具和語言 | 範例 | 參考 | 書籍評論 |
| grep | PowerGREP | RegexBuddy | RegexMagic |
| EditPad Lite | EditPad Pro |
| Boost | Delphi | GNU (Linux) | Groovy | Java | JavaScript | .NET | PCRE (C/C++) | PCRE2 (C/C++) | Perl | PHP | POSIX | PowerShell | Python | R | Ruby | std::regex | Tcl | VBScript | Visual Basic 6 | wxWidgets | XML Schema | Xojo | XQuery 和 XPath | XRegExp |
| MySQL | Oracle | PostgreSQL |
頁面網址:https://regular-expressions.dev.org.tw/stdregex.html
頁面最後更新時間:2021 年 11 月 5 日
網站最後更新時間:2024 年 3 月 15 日
版權所有 © 2003-2024 Jan Goyvaerts。保留所有權利。