最近本人用正则表达式开发项目比较多,有时候调试程序,会发现编译不过去,提示[DCC Error]F2084 Internal Error:l3576
经过排查,发现时使用了TPerlRegEx控件的问题,我使用的是静态编译方法,即程序发布后不需要pcre.dll。拿代码说话:
procedure TMainForm.Button1Click(Sender:TObject); var RegEx:TPerlRegEx; begin RegEx:=TPerlRegEx.Create(nil); RegEx.RegEx:= '<*.?>'; RegEx.Subject:= '<test>aaa</test>'; FreeAndNil(RegEx); end;
这段代码在编译的时候就会出上述错误,但只要注释掉 RegEx 对象的构造语句,就能编译通过(尽管点击Button1按钮后会报错)。
后来意外地发现,上述代码中只要在指定了Subject之后,写上匹配处理就可以正常编译。更改后的代码为:
procedure TMainForm.Button1Click(Sender:TObject); var RegEx:TPerlRegEx; begin RegEx:=TPerlRegEx.Create(nil); RegEx.RegEx:= '<*.?>'; RegEx.Subject:= '<test>aaa</test>'; if RegEx.Match then begin //do nothing end; FreeAndNil(RegEx); end;
思考后,个人觉得,这是由 TPerlRegEx 控件的特殊性决定的,该控件是由BCB编译器将 pcre 源码编译后,将生成的obj文件与Delphi连接实现的。在正则表达式被引入到一个工程中的时候,一旦使用正则表达式,就会在项目生成时对其进行编译,对于一个空的匹配处理,触发了某种异常。另外根据 TPerlRegEx 的官方文档,提到了一个Study方法和一个Compiled属性。文档中显示,使用Study方法可以将正则表达式编译,在执行的时候会加快执行速度。Compiled属性来判断该正则表达式是否被成功编译。
可能还有别的情况可以触发这一异常,我没有过多去探索,希望高手们来补充!
最后补充一下,我所使用的平台为Windows XP + Delphi 2007