Sign in Join
Wiki copytemporary

RegEx packages/zh CN

Bahasa Indonesia · Deutsch · English · Español · Polski · 中文(中国)

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.

Revision 1, last changed by WikiArchive .

Talk about this page

Nobody has opened a bench for this page yet. Sign in to open one.