Sign in Join
Wiki copytemporary

Revision 1 of 1, by WikiArchive on 11-9-2026. The page as it is now.

RegEx packages/zh CN

Free Pascal 包含 RegExpr 包,该包包含多个用于正则表达式的“引擎”。其中主要的引擎是 TRegExpr,其他引擎已被弃用且不再开发。

阅读关于正则表达式的 Wikipedia 页面以了解该主题:POSIX 基本正则表达式。

Sorokin 的 TRegExpr

这是最完整的实现,在 FPC 的 "packages/regexpr/src/regexpr.pas" 文件中可用。此包实现了 Perl 正则表达式的一个子集,并且该包提供的语法在 这里有文档说明。

官方仓库:GitHub。开发在那里进行,FPC 包会稍晚一些跟随这个仓库。来自该仓库的版本在 FPC 中运行良好。

2019/2020 年的改进

在 2019 年之前,大约 15 年没有任何人提交补丁之后,Alexey Torgashin 和 User:Alextp 继续了 TRegExpr 的工作。这些更改已合并到 FPC Git 的“main”分支中。

更改包括:

2023 年的改进

在 2023 年,Martin Friebe(SynEdit 维护者)进行了许多很好的更改。

这些更改也已合并到 FPC TRegExpr 分支中。

来自 Alexey Torgashin 的贡献:

替换时更改大小写

您可以更改找到的片段的大小写,在替换字段中使用修饰符(大小写更改在修饰符位置之后生效):

例如,如果找到了一个单词,使用替换字段 "\L$0" 将单词转换为小写(这里 $0 是组 0,即找到的文本)。

此外,\n 将被替换为换行符(LF 或 CR LF,这取决于内部常量)。

示例

使用 TRegExpr 检查字符串中是否存在表达式非常简单,只需创建 TRegExpr 的一个实例,然后将您的正则表达式放入 TRegExpr.Expression 属性中,并使用 Exec 方法来验证该正则表达式是否有任何匹配项。如果表达式与传递给它的字符串匹配,Exec 将返回 true。

pascal
var
      RegexObj: TRegExpr;
    begin
      RegexObj := TRegExpr.Create;
      RegexObj.Expression := '.*login.*';
      if RegexObj.Exec('Please try to login here') then WriteLn('The login was found!');
      RegexObj.Free;
    end;

子表达式匹配:

pascal
program Project1;
    
    uses
      RegExpr;
    
    var
      re: TRegExpr;
    begin
      re := TRegExpr.Create('hello (.*?)!');
      if re.Exec('hello world! hello pascal!') then
      begin
        WriteLn(re.Match[1]);
        while re.ExecNext do
        begin
          WriteLn(re.Match[1]);
        end;
      end;
      re.Free;
    end.

输出:

pascal
world
    pascal

FLRE - 快速轻量级正则表达式

FLRE(F ast L ight R egular E xpressions)是一个快速、安全且高效的正则表达式库,它使用Object Pascal(Delphi和Free Pascal)实现,但也可以从其他语言如C/C++等中使用。它能够处理Unicode和UTF-8字符串。

它实现了许多最常见的Perl和POSIX特性,除了像前向引用和嵌套反向引用等不规则表达式特性,这些在FLRE中不受支持,只支持真正的"反向引用",这也是FLRE名称中“Light”一词的由来。它还查找最左最先匹配项,与Perl和PCRE相同,并能返回子匹配信息。但它还包含一个标志,用于实验性的POSIX风格的最左最长匹配行为模式。

FLRE在LGPL v2.1静态链接异常下获得许可。

GitHub仓库

示例

实现PHP的parse_url函数(基于php.js parse_url实现)

pascal
uses Classes, SysUtils, flre;
    
    type
      RUrlParser = record
      private
        Fcomponents: array[1..13] of string;
      private
        function getComponent(aIndex: integer): string;
        procedure setComponent(aIndex: integer; const aValue: string);
      public
        function parse(const aUrl: UTF8String): boolean;
      public
        property scheme: string index 1 read getComponent write setComponent; // 例如 http
        property authority: string index 2 read getComponent;
        property userInfo: string index 3 read getComponent;
        property user: string index 4 read getComponent;
        property pass: string index 5 read getComponent;
        property host: string index 6 read getComponent;
        property port: string index 7 read getComponent;
        property path: string index 9 read getComponent;
        property directory: string index 10 read getComponent;
        property fileName: string index 11 read getComponent;
        property query: string index 12 read getComponent; // 问号(?)之后
        property fragment: string index 13 read getComponent; // 井号(#)之后
      end;
    
    implementation
    
    function RUrlParser.getComponent(aIndex: integer): string;
    begin
        Result := Fcomponents[aIndex];
    end;
    
    procedure RUrlParser.setComponent(aIndex: integer; const aValue: string);
    begin
        Fcomponents[aIndex] := aValue;
    end;
    
    function RUrlParser.parse(const aUrl: UTF8String): boolean;
    var
        i: integer;
        re: TFLRE;
        parts: TFLREMultiStrings;
    begin
        re := TFLRE.Create(
          '(?:([^:\\/\?#]+):)?'
          + '(?:\/\/()(?:(?:()(?:([^:@\/]*):?([^:@\/]*))?@)?([^:\/?#]*)(?::(\d*))?))?'
          + '()'
          + '(?:(()(?:(?:[^?#\/]*\/)*)()(?:[^?#]*))(?:\?([^#]*))?(?:#(.*))?)'
          , [rfUTF8]
        ); 
    
        parts := nil;
        Result := re.UTF8ExtractAll(aUrl, parts);
        if Result then
        begin
            for i := 1 to Length(parts[0]) - 1 do
            begin
                setComponent(i, string(parts[0][i]));
            end;
        end;
    
        // 释放正则表达式内存
        for i := 0 to Length(parts) - 1 do
        begin
            SetLength(parts[i], 0);
        end;
        parts := nil;
    
        re.Free();
    end;

Joost的Regexpr

Joost的Regexpr(单元为oldregexpr.pp和regex.pp)是一个非常基本的正则表达式单元,它处理大多数正则表达式,类似于GNU regexpr。

当前的单元还远未完成,仍然缺少对POSIX或更复杂的语法如Perl regex、Java Regex、Ruby Regex等的非常简单的语法支持。

该单元目前包含4个函数:

还有一个测试:

Florian的Regexpr

这是最早的实现。它存在于packages/regexpr/src/old中,并且当前不被makefile编译,因此在发布的FPC/Lazarus版本中默认不可用预编译版本。


From the Free Pascal wiki, page "RegEx packages/zh CN", as the Internet Archive kept it on 2025-07-05, last changed on 2024-07-21. Copyright stays with the author who wrote it, according to the old wiki's Licensing page. If you have concerns about this material, message the admin.