正则表达式工具 |
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 |
此网站上的更多信息 |
简介 |
正则表达式快速入门 |
正则表达式教程 |
替换字符串教程 |
应用程序和语言 |
正则表达式范例 |
正则表达式参考 |
替换字符串参考 |
Delphi 正则表达式类别
Delphi XE 是第一个内置支持正则表达式的 Delphi 版本。在多数情况下,您会使用 RegularExpressions 单元。此单元定义了一组记录,用来仿真 .NET 架构中的正则表达式类别。就像在 .NET 中一样,它们让您只要一行代码就能使用正则表达式,而且不需要明确的内存管理。
RegularExpressions 单元在内部使用 RegularExpressionsCore 单元,而后者定义了 TPerlRegEx 类别。TPerlRegEx 是由本网站作者开发的开源 PCRE 函数库 的包装函数。因此,RegularExpressions 和 RegularExpressionsCore 单元都会使用 PCRE 正则表达式风格。
Delphi 的 RegularExpressions 单元
RegularExpressions 单元将 TRegEx
、TMatch
、TMatchCollection
、TGroup
和 TGroupCollection
定义为记录,而不是类别。这表示您不需要调用 Create
和 Free
来配置和释放内存。
TRegEx
有个 Create
建构函数,如果你想要使用同一个正则表达式多次,你可以调用它。这样 TRegEx
就不会编译同一个正则表达式两次。如果你调用建构函数,你就可以调用任何不以正则表达式为参数的非静态方法。如果你没有调用建构函数,你只能调用以正则表达式为参数的静态(类别)方法。所有 TRegEx
方法都有静态和非静态的重载。你使用哪一个只取决于你是否想要使用同一个正则表达式调用 TRegEx
多次。
IsMatch
方法会接受一个字符串并回传 True 或 False,表示正则表达式是否符合(字符串的一部分)。
Match
方法会接受一个字符串并回传一个包含第一个符合项目的详细数据的 TMatch
记录。如果符合失败,它会回传一个 TMatch
记录,其中 Success
属性设为 nil
。 Match()
的非静态重载会接受一个选用的起始位置和一个选用的长度参数,你可以使用它来只搜索输入字符串的一部分。
Matches
方法会接受一个字符串并回传一个 TMatchCollection
记录。这个记录的缺省 Item[]
属性会包含一个 TMatch
,表示正则表达式在字符串中找到的每个符合项目。如果没有任何符合项目,回传的 TMatchCollection
记录的 Count
属性会是零。
使用 Replace
方法来搜索并取代字符串中的所有符合项目。你可以传递一个 TMatchEvaluator
,它只是一个方法,它会接受一个称为 Match
的 TMatch
类型的参数并回传一个字符串。你的方法回传的字符串会用作一个文本替换字符串。如果你想要在使用 TMatchEvaluator
重载时替换字符串中的反向引用,请在回传字符串之前调用提供的 Match
参数上的 Result
方法。
使用 Split
方法来沿着其 regex 比对分割字符串。结果以动态字符串数组传回。与 .NET 中相同,在正则表达式中由 捕获组 比对的文本也包含在传回的数组中。如果您不喜欢这样,请从您的 regex 中移除所有 命名捕获组,并传递 roExplicitCapture
选项来禁用编号捕获组。 Split()
的非静态重载会采用一个选用的 Count
参数,以指出传回数组可能拥有的最大元素数。换句话说,字符串最多会分割 Count-1
次。捕获组比对不包含在计算中。因此,如果您的 regex 具有捕获组,传回的数组可能会有超过 Count
个元素。如果您传递 Count
,您可以传递第二个选用参数,以指出字符串中开始分割的位置。传回数组的第一个元素会传回未分割的字符串起始位置之前的部分。
TMatch
记录提供几个有关比对的详细信息的属性。 Success
指出是否找到比对。如果这是 False,所有其他属性和方法都是无效的。 Value
传回比对的字符串。 Index
和 Length
指出输入字符串中的位置和比对的长度。 Groups
传回一个 TGroupCollection 记录,它在缺省的 Item[]
属性中为每个捕获组保存一个 TGroup
记录。您可以使用数字索引来 Item[]
编号捕获组,并使用字符串索引来 命名捕获组。
TMatch
也提供两个方法。 NextMatch
传回这个之后的正则表达式的下一个比对。如果您的 TMatch
是 TMatchCollection
的一部分,您不应该使用 NextMatch
来取得下一个比对,而是应该使用 TMatchCollection.Item[]
,以避免重复搜索。 TMatch.Result
采用一个参数,其中包含替换文本作为字符串。它传回如果您使用这个替换文本与 TRegEx.Replace
,这个比对将会被替换的字符串。
TGroup
记录具有 Success
、Value
、Index
和 Length
属性,它们的工作方式就像 TMatch
的那些属性。
在 Delphi XE5 及之前版本中,TRegEx 始终会略过长度为零的比对。这已在 Delphi XE6 中修正。您可以通过修改 RegularExpressionsCore.pas 来移除 TPerlRegEx.Create
中的 State := [preNotEmpty]
行,在 XE5 及之前版本中进行相同的修正。这个变更也会影响直接使用 TPerlRegEx 而未设置 State
属性的代码。
较旧版本的 Delphi 的正则表达式类别
TPerlRegEx 在 Embarcadero 授权一份副本以包含在 Delphi XE 中之前就已经可以使用了。根据您的需求,您可以下载两个版本之一,以搭配 Delphi 2010 及更早版本使用。
TPerlRegEx 的最新版本与 Delphi XE 中的 RegularExpressionsCore 单元完全兼容。对于以 Delphi 2010 或更早版本编写的新代码,强烈建议使用 TPerlRegEx 的最新版本。如果您稍后将代码移转到 Delphi XE,您所要做的就是将 PerlRegEx 取代为单元的 uses 子句中的 RegularExrpessionsCore。
较旧版本的 TPerlRegEx 是非视觉组件。这表示您可以将 TPerlRegEx 放到组件面板上,并将它拖放到表单上。最初的 TPerlRegEx 是在 Borland 的目标是让组件面板上的所有东西都有组件时开发的。
如果您想要从较旧版本的 TPerlRegEx 移转到最新的 TPerlRegEx,请从移除您可能已放置在表单或数据模块上的任何 TPerlRegEx 组件开始,并在运行阶段实例化对象。在运行阶段实例化时,您不再需要将拥有者组件传递给 Create()
构造函数。只要移除参数即可。
最初的 TPerlRegEx 中的一些属性和方法名称有点难以处理。这些名称已在最新的 TPerlRegEx 中重命名。基本上,在所有识别码中,SubExpression
已被 Group
取代,而 MatchedExpression
已被 Matched
取代。以下是已变更识别码的完整清单
旧识别码 | 新识别码 |
---|---|
StoreSubExpression | StoreGroups |
NamedSubExpression | NamedGroup |
MatchedExpression | MatchedText |
MatchedExpressionLength | MatchedLength |
MatchedExpressionOffset | MatchedOffset |
SubExpressionCount | GroupCount |
SubExpressions | Groups |
SubExpressionLengths | GroupLengths |
SubExpressionOffsets | GroupOffsets |
UTF-8 与 UTF-16
您需要留意的其中一件事是,您可以在这里下载的 TPerlRegEx 版本,以及包含在 Delphi XE、XE2 和 XE3 中的版本,都使用 UTF8String 属性,而所有 Offset 和 Length 属性都是这些 UTF-8 字符串的索引。这是因为当时 PCRE 只支持 UTF-8,而使用 UTF8String 可以避免重复转换。如果性能至关重要,您应该在这些 Delphi 版本中使用 TPerlRegEx,而不是 TRegEx。如果您的数据已经是 UTF-8,您可以将 UTF-8 直接传递给 TPerlRegEx。如果您的数据使用其他编码,您可以控制转换为 UTF-8 的时间,以避免重复转换相同的数据。
在 Delphi XE4 和 XE5 中,TPerlRegEx 具有 UnicodeString(UTF-16)属性,但仍然传回 UTF-8 的偏移量和长度。在 Delphi XE6 中,Offset 和 Length 属性已变更为 UTF-16 的偏移量和长度。这表示如果您的字符串包含非 ASCII 字符,使用 Offset 和 Length 属性的 XE3 或 XE6 兼容代码将无法与 XE4 和 XE5 兼容。从 Delphi XE4 到 Delphi 10 到 10.2,持续使用 UTF-8 版本的 PCRE,即使 PCRE 已经具有原生 UTF-16 支持。这与使用 UnicodeString 相结合,表示在 UTF-16 和 UTF-8 之间进行持续转换,这可能会大幅降低正则表达式的性能,特别是对于长的主旨字符串。
Delphi 10.3 和更新版本在 Windows 平台上使用 UTF-16 版本的 PCRE。TRegEx 和 TPerlRegEx 现在对所有内容都使用 UnicodeString,而不会转换为 UTF-8。从 Delphi XE4 或更新版本升级到 10.3 或更新版本,绝对会改善任何使用 TRegEx 或 TPerlRegEx 的代码性能。从 Delphi XE3 或更早版本升级会改善性能,除非您对所有内容都使用 UTF-8。
与 Delphi Prism 搭配使用 System.Text.RegularExpressions
Delphi Prism 是 Embarcadero 的 Delphi 语言变体,专门开发为针对 .NET 架构。Delphi Prism 存在于 Visual Studio IDE 中。它完全基于 .NET 架构。在 Delphi Prism 中,您可以简单地将 System.Text.RegularExpressions 命名空间添加到单元的 uses 子句。然后,您可以访问 .NET 正则表达式类别,例如 Regex、Match 和 Group。您可以使用 Delphi Prism,就像 C# 和 VB 开发人员可以使用它们一样。
与 Delphi for .NET 搭配使用 System.Text.RegularExpressions
Delphi 8、2005、2006 和 2007 包含一个 Delphi for .NET 编译器,用于开发 WinForms 和 VCL.NET 应用程序。尽管 Delphi for .NET 只支持 .NET 1.1 或 2.0(视您的 Delphi 版本而定),但您仍然可以使用 .NET 的完整正则表达式支持。您只需要将 System.Text.RegularExpressions 命名空间添加到单元的 uses 子句,就能够访问所有 .NET 正则表达式类别。