正则表达式工具 |
grep |
语言和函数库 |
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 |
本网站的更多内容 |
简介 |
正则表达式快速入门 |
正则表达式教程 |
替换字符串教程 |
应用程序和语言 |
正则表达式范例 |
正则表达式参考 |
替换字符串参考 |
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 引擎消除了令人困惑的「单行」 和「多行」
比对模式,并以同样令人困惑的「不区分换行」
、「部分区分换行」
、「反向部分区分换行」
和「区分换行比对」
取代它们。由于 wxRegEx 类别封装 ARE 引擎,因此当您在正则表达式中使用模式修改器时,它支持所有 4 种模式。但
flags
参数只允许您设置两个。
如果您将 wxRE_NEWLINE 加入旗标,您将打开「换行敏感比对」。在此模式中,点 将不比对换行字符 (\n)。插入符号和美元符号 将比对字符串中换行字符的前后,以及主旨字符串的开头和结尾。
如果您未设置 wxRE_NEWLINE 旗标,缺省为「非换行敏感」。在此模式中,点 将比对所有字符,包括换行字符 (\n)。插入符号和美元符号 将只比对主旨字符串的开头和结尾。请注意,此默认值与 Perl 和地球上其他所有正则表达式引擎的默认值不同。在 Perl 中,缺省情况下,点不比对换行字符,插入符号和美元符号只比对主旨字符串的开头和结尾。在 wxWidgets 中设置此模式的唯一方法是在正则表达式的开头加上
。
将所有内容放在一起,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")
。