快速入门
教程
工具和语言
示例
参考
书籍评论
正则表达式工具
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 模式
Xojo
XQuery 和 XPath
XRegExp
数据库
MySQL
Oracle
PostgreSQL
本网站上的更多内容
简介
正则表达式快速入门
正则表达式教程
替换字符串教程
应用程序和语言
正则表达式示例
正则表达式参考
替换字符串参考
书籍评论
可打印 PDF
关于本网站
RSS 提要和博客
RegexBuddy—The best regex editor and tester for Delphi developers!

Delphi 正则表达式类

Delphi XE 是第一个内置支持正则表达式的 Delphi 版本。在大多数情况下,您将使用 RegularExpressions 单元。此单元定义了一组记录,它们模仿 .NET 框架中的正则表达式类。与 .NET 中一样,它们允许您在不显式进行内存管理的情况下仅使用一行代码中的正则表达式。

在内部,RegularExpressions 单元使用 RegularExpressionsCore 单元,该单元定义了 TPerlRegEx 类。TPerlRegEx 是一个包装器,用于由本网站作者开发的开源 PCRE 库。因此,RegularExpressions 和 RegularExpressionsCore 单元都使用 PCRE 正则表达式风格。

Delphi 的 RegularExpressions 单元

RegularExpressions 单元将 TRegExTMatchTMatchCollectionTGroupTGroupCollection 定义为记录,而不是类。这意味着您无需调用 CreateFree 来分配和释放内存。

TRegEx 确实有一个 Create 构造函数,如果您想多次使用同一正则表达式,则可以调用该构造函数。这样,TRegEx 不会两次编译同一正则表达式。如果您调用构造函数,则可以调用任何不将正则表达式作为参数的非静态方法。如果您不调用构造函数,则只能调用将正则表达式作为参数的静态(类)方法。所有 TRegEx 方法都有静态和非静态重载。您使用哪种方法完全取决于您是否希望使用同一正则表达式对 TRegEx 进行多次调用。

IsMatch 方法获取一个字符串,并返回 True 或 False,以指示正则表达式是否匹配(部分)字符串。

Match 方法获取一个字符串,并返回一个 TMatch 记录,其中包含第一个匹配项的详细信息。如果匹配失败,它将返回一个 TMatch 记录,其中 Success 属性设置为 nilMatch() 的非静态重载获取一个可选的起始位置和一个可选的长度参数,您可以使用它们仅搜索输入字符串的一部分。

Matches 方法获取一个字符串并返回一个 TMatchCollection 记录。此记录的默认 Item[] 属性为正则表达式在字符串中找到的每个匹配项保存一个 TMatch。如果没有匹配项,则返回的 TMatchCollection 记录的 Count 属性为零。

使用 Replace 方法搜索并替换字符串中的所有匹配项。你可以使用 JGsoft 替换文本样式将替换文本作为字符串传递。或者,你可以传递一个 TMatchEvaluator,它只是一个方法,它获取一个名为 MatchTMatch 类型参数,并返回一个字符串。你的方法返回的字符串用作一个文字替换字符串。如果你希望在使用 TMatchEvaluator 重载时替换字符串中的反向引用,请在返回字符串之前调用提供的 Match 参数上的 Result 方法。

使用 Split 方法沿着其正则表达式匹配项拆分一个字符串。结果作为字符串的动态数组返回。与 .NET 中一样,正则表达式中 捕获组 匹配的文本也包含在返回的数组中。如果你不喜欢这样,请从你的正则表达式中删除所有 命名的捕获组,并传递 roExplicitCapture 选项以禁用编号捕获组。 Split() 的非静态重载获取一个可选的 Count 参数来指示返回的数组可以具有的最大元素数。换句话说,字符串最多拆分 Count-1 次。捕获组匹配项不包含在计数中。因此,如果你的正则表达式有捕获组,则返回的数组可能具有多于 Count 的元素。如果你传递 Count,则可以传递第二个可选参数来指示在字符串中开始拆分的起始位置。返回的数组的第一个元素中返回起始位置之前的字符串部分,未拆分。

TMatch 记录提供了几个属性,其中包含有关匹配项的详细信息。 Success 指示是否找到匹配项。如果为 False,则所有其他属性和方法都是无效的。 Value 返回匹配的字符串。 IndexLength 指示输入字符串中的位置和匹配项的长度。 Groups 返回一个 TGroupCollection 记录,它在其默认 Item[] 属性中为每个捕获组存储一个 TGroup 记录。你可以使用一个数字索引来获取 Item[] 以获取编号捕获组,并使用一个字符串索引来获取 命名的捕获组

TMatch 还提供了两种方法。 NextMatch 返回此正则表达式之后的下一个匹配项。如果您的 TMatchTMatchCollection 的一部分,则不应使用 NextMatch 获取下一个匹配项,而应使用 TMatchCollection.Item[],以避免重复搜索。 TMatch.Result 使用 JGsoft 替换文本风格将一个参数作为字符串替换文本。它返回如果使用 TRegEx.Replace 使用此替换文本,此匹配项将替换成的字符串。

TGroup 记录具有 SuccessValueIndexLength 属性,这些属性的工作方式与 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,您只需在单元的 uses 子句中将 PerlRegEx 替换为 RegularExrpessionsCore。

较早版本的 TPerlRegEx 是非可视组件。这意味着您可以在组件面板上放置 TPerlRegEx 并将其拖放到窗体上。最初的 TPerlRegEx 是在 Borland 的目标是在组件面板上为所有内容提供组件时开发的。

如果您想从较早版本的 TPerlRegEx 迁移到最新的 TPerlRegEx,请首先移除您可能已放置在窗体或数据模块上的任何 TPerlRegEx 组件,然后在运行时实例化对象。在运行时实例化时,您不再需要将所有者组件传递给 Create() 构造函数。只需移除该参数即可。

原始 TPerlRegEx 中的一些属性和方法名称有点难以处理。这些名称已在最新的 TPerlRegEx 中重命名。实质上,在所有标识符中,SubExpression 已替换为 GroupMatchedExpression 已替换为 Matched。以下是已更改标识符的完整列表

旧标识符新标识符
StoreSubExpression存储组
命名子表达式命名组
匹配表达式匹配文本
匹配表达式长度匹配长度
匹配表达式偏移匹配偏移
子表达式计数组计数
子表达式
子表达式长度组长度
子表达式偏移组偏移

如果您正在使用 RegexBuddy 或 RegexMagic 来 生成 Delphi 代码片段,请将语言设置为“Delphi (TPerlRegEx)”以使用旧标识符,或设置为“Delphi XE (Core)”以使用新标识符,而不管您实际使用的是哪个(较旧)版本的 Delphi。

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