快速入門
教學
工具和語言
範例
參考
書籍評論
正規表示式工具
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 和部落格
RegexBuddy—The best regex editor and tester for wxWidgets developers!

wxWidgets 支援三種正規表示式風格

wxWidgets 使用 Henry Spencer 為 Tcl 8.2 開發的完全相同的正規表示式引擎。這表示 wxWidgets 支援相同的三種正規表示式風格:Tcl 進階正規表示式POSIX 延伸正規表示式POSIX 基本正規表示式。與 Tcl 不同的是,ERE 而不是功能強大的 ARE 是預設值。wxRegEx::Replace() 方法使用與 Tcl 的 regsub 指令相同的語法作為替換文字。

wxRegEx 類別

若要使用 wxWidgets 正規表示式引擎,您需要實例化 wxRegEx 類別。該類別有兩個建構函式。wxRegEx() 會建立一個空的正規表示式物件。在使用物件之前,您必須呼叫 wxRegEx::Compile()wxRegEx::IsValid 會傳回 false,直到您執行此動作。

wxRegEx(const wxString& expr, int flags = wxRE_EXTENDED) 會建立一個包含已編譯正規表示式的 wxRegEx 物件。即使您的正規表示式無效,建構函式仍會建立物件。檢查 wxRegEx::IsValid 以確定正規表示式是否已成功編譯。

bool wxRegEx::Compile(const wxString& pattern, int flags = wxRE_EXTENDED) 編譯正規表示式。您可以在任何 wxRegEx 物件上呼叫此方法,包括已包含編譯正規表示式的物件。這樣做只會取代 wxRegEx 物件所包含的正規表示式。將您的正規表示式作為字串傳遞,作為第一個參數。第二個參數允許您設定某些比對選項。

若要設定 regex 風格,請指定旗標 wxRE_EXTENDED、wxRE_ADVANCED 或 wxRE_BASIC 之一。如果您指定一種風格,wxRE_EXTENDED 為預設值。我建議您始終指定 wxRE_ADVANCED 旗標。ARE 遠比 ERE 強大。每個有效的 ERE 也是有效的 ARE,且會產生相同的結果。使用 ERE 風格的唯一原因是當您的程式碼必須在未編譯「內建」正規表示式函式庫(即 Henry Spencer 的程式碼)的情況下使用 wxWidgets 時。

除了風格之外,您還可以設定其他三個旗標。wxRE_ICASE 使正規表示式不區分大小寫。預設值區分大小寫。wxRE_NOSUB 使 regex 引擎將所有 擷取群組 視為非擷取。這表示您無法在替換文字中使用反向參照,或查詢每個擷取群組比對的 regex 部分。如果您不會使用這些功能,設定 wxRE_NOSUB 旗標可提升效能。

Tcl 區段所述,Henry Spencer 的「ARE」regex 引擎消除了令人困惑的「單行」(?s) 和「多行」(?m) 比對模式,並以同樣令人困惑的「不區分換行」(?s)、「部分區分換行」(?p)、「反向部分區分換行」(?w) 和「區分換行比對」(?n) 取代它們。由於 wxRegEx 類別封裝 ARE 引擎,因此當您在正規表示式中使用模式修改器時,它支援所有 4 種模式。但 flags 參數只允許您設定兩個。

如果您將 wxRE_NEWLINE 加入旗標,您將開啟「換行敏感比對」(?n)。在此模式中, 將不比對換行字元 (\n)。插入符號和美元符號 將比對字串中換行字元的前後,以及主旨字串的開頭和結尾。

如果您未設定 wxRE_NEWLINE 旗標,預設為「非換行敏感」(?s)。在此模式中, 將比對所有字元,包括換行字元 (\n)。插入符號和美元符號 將只比對主旨字串的開頭和結尾。請注意,此預設值與 Perl 和地球上其他所有正規表示式引擎的預設值不同。在 Perl 中,預設情況下,點不比對換行字元,插入符號和美元符號只比對主旨字串的開頭和結尾。在 wxWidgets 中設定此模式的唯一方法是在正規表示式的開頭加上(?p)

將所有內容放在一起,wxRegex(_T("(?p)^[a-z].*$"), wxRE_ADVANCED + wxRE_ICASE) 將檢查您的主旨字串是否包含以字母開頭的單行。Perl 中的等效表示式為 m/^[a-z].*$/i

wxRegEx 狀態函式

wxRegEx::IsValid() 在 wxRegEx 物件包含已編譯的正規表示式時傳回 true。

wxRegEx::GetMatchCount() 的命名相當不恰當。它不會傳回 Matches() 找到的比對數。事實上,您可以在 Compile() 之後、呼叫 Matches 之前,立即呼叫 GetMatchCount()GetMatchCount() 會傳回正規表示式中擷取群組的數量,再加上整體正規表示式比對的數量。您可以使用此資訊來確定您可以在替換文字中使用的反向參照數量,以及您可以傳遞給 GetMatch() 的最高索引。如果您的正規表示式沒有擷取群組,GetMatchCount() 會傳回 1。在這種情況下,\0 是您可以在替換文字中使用的唯一有效反向參照。

發生錯誤時,GetMatchCount() 會傳回 0。如果 wxRegEx 物件不包含已編譯的正規表示式,或者您使用 wxRE_NOSUB 編譯它,就會發生這種情況。

尋找和擷取比對

如果您想要測試正規表示式是否比對字串,或擷取正規表示式比對的子字串,您首先需要呼叫 wxRegEx::Matches() 方法。它有 3 個變體,讓您可以傳遞 wxChar 或 wxString 作為主旨字串。使用 wxChar 時,您可以將長度指定為第三個參數。如果您不這樣做,系統將呼叫 wxStrLen() 來計算長度。如果您計畫逐一迴圈處理字串中的所有正規表示式比對,您應該在迴圈外自行呼叫 wxStrLen(),並將結果傳遞給 wxRegEx::Matches()。

bool wxRegEx::Matches(const wxChar* text, int flags = 0) const
bool wxRegEx::Matches(const wxChar* text, int flags, size_t len) const
bool wxRegEx::Matches(const wxString& text, int flags = 0) const

Matches() 傳回 true,表示 regex 與您在 text 參數中傳入的主旨字串全部或部分相符。如果您想設定 regex 是否與整個主旨字串相符,請將 錨點 加入您的 regex。

不要將 flags 參數與傳遞給 Compile() 方法或 wxRegEx() 建構函式的參數混淆。所有風味和比對模式選項只能在編譯 regex 時設定。

Matches() 方法只允許兩個旗標:wxRE_NOTBOL 和 wxRE_NOTEOL。如果您設定 wxRE_NOTBOL,則 ^\A 將不會與字串開頭相符。如果您已開啟該比對模式,它們仍會在嵌入換行符號後相符。同樣地,指定 wxRE_NOTEOL 會告知 $\Z 不要與字串結尾相符。

wxRE_NOTBOL 通常用於實作「尋找下一個」常式。wxRegEx 類別未提供此類函式。若要找出字串中的第二個相符項,您需要呼叫 wxRegEx::Matches(),並傳遞第一個相符項後原始主旨字串的部分。傳遞 wxRE_NOTBOL 旗標,以表示您已切斷所傳遞字串的開頭。

如果您正在處理大量資料,且您想在讀取完整資料前套用 regex,則 wxRE_NOTEOL 可能會很有用。只要您尚未讀取完整字串,請在呼叫 wxRegEx::Matches() 時傳遞 wxRE_NOTEOL。在對不完整資料進行「尋找下一個」時,請同時傳遞 wxRE_NOTBOL 和 wxRE_NOTEOL。

在呼叫 Matches() 傳回 true 之後,且您在未設定 wxRE_NOSUB 旗標的情況下編譯 regex,您可以呼叫 GetMatch() 以取得關於整體 regex 相符項和 regex 中 擷取群組 所相符字串部分的詳細資料。

bool wxRegEx::GetMatch(size_t* start, size_t* len, size_t index = 0) const 擷取相符項在主旨字串中的起始位置和相符項中的字元數。

wxString wxRegEx::GetMatch(const wxString& text, size_t index = 0) const 傳回相符的文字。

對於這兩個呼叫,將 index 參數設定為零(或省略它)以取得整體 regex 相符項。設定 1 <= index < GetMatchCount() 以取得正規表示式中擷取群組的相符項。若要判斷群組的數量,請從左至右計算正規表示式中的開啟括號。

搜尋和取代

wxRegEx 類別提供三個方法來執行搜尋和取代。 Replace() 是執行實際工作的函式。您可以使用 ReplaceAll()ReplaceFirst() 作為更易於閱讀的方式來指定 Replace() 的第 3 個參數。

int wxRegEx::ReplaceAll(wxString* text, const wxString& replacement) const 會以 replacement 取代 text 中所有符合正規表示式的部分。

int wxRegEx::ReplaceFirst(wxString* text, const wxString& replacement) const 會以 replacement 取代 text 中符合正規表示式的第一個部分。

int wxRegEx::Replace(wxString* text, const wxString& replacement, size_t maxMatches = 0) const 允許您指定要取代的次數。傳遞 0 給 maxMatches 或省略它會執行與 ReplaceAll() 相同的動作。設定為 1 會執行與 ReplaceFirst() 相同的動作。傳遞大於 1 的數字只會取代前 maxMatches 個符合的部分。如果 text 包含的符合部分比您要求的少,則會取代所有符合的部分,而不會觸發錯誤。

這三個呼叫都會傳回實際取代的次數。如果正規表示式無法符合主旨文字,則會傳回 0。傳回值 -1 表示錯誤。取代會直接對您傳遞為第一個參數的 wxString 執行。

wxWidgets 使用與 Tcl 相同的語法作為取代文字。您可以使用 \0 作為整個正規表示式符合部分的佔位符,並使用 \1\9 作為符合前九個 擷取群組 之一文字的佔位符。您也可以使用 & 作為 \0 的同義字。請注意,& 前面沒有反斜線。 & 會以整個正規表示式符合部分取代,而 \& 會以一個字面上的 & 取代。使用 \\ 插入一個字面上的反斜線。您只需要在反斜線後接數字時才需要跳脫反斜線,以避免組合被視為反向參照。當在 C++ 程式碼中指定取代文字為字面上的字串時,您需要將所有反斜線加倍,因為 C++ 編譯器也會將反斜線視為跳脫字元。因此,如果您想用第一個反向參照加上文字 &co 取代符合部分,您需要在 C++ 中將其編碼為 _T("\\1\\&co")

| 快速入門 | 教學 | 工具與語言 | 範例 | 參考 | 書籍評論 |

| 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 |