2

私のプロジェクトでは、正規表現を使用して 400MB の TMemoryStream オブジェクト内のデータを検索する必要があります。Delphi xe3 内の新しい正規表現をチェックしていますが、関数は受信した文字列パラメーターとのみ一致し、rawbytestring やポインターは一致しません。私はこの方法でパターンを定義しました:

MyPatt:="\x8A\x8A(..)\x8A"

問題は、私が試したバイナリ生データ内を見つける方法です

TRegex.Match((MyStreamObject.Memory)^,MyPatt);

しかし、成功しません。私はこれを試してみましたが、成功しませんでした

TRegex.Match(String((MyStreamObject.Memory)^),MyPatt);

bcz 問題は、0x00 で始まる rawbinary オブジェクトが切り捨てられた場合です。

ポインターまたは rawbinarystring を使用して正規表現を一致させるにはどうすればよいですか?

4

1 に答える 1

6

文字列ベースの Delphi クラスの代わりに、RegEx ライブラリ API を直接使用できます。Delphi クラスには、特定された(および修正されていない)パフォーマンスの問題がいくつかあります。

たとえば (XE5 までの Delphi 6 と互換性があります):

uses
{$ifdef ISDELPHIXE}
  // use direct PCRE library as available since Delphi XE
  RegularExpressionsAPI,
{$else}
  // download from http://www.regular-expressions.info/download/TPerlRegEx.zip
  PCRE,
{$endif}
  SysUtils,
  ...

var
  compiled: PPCRE;
  extra: PPCREExtra;
  errMsg: PAnsiChar;
  errPos: integer;

  // here regexp points to your null-terminated regular expression
  compiled := pcre_compile(PAnsiChar(regexp),0,@errMsg,@errPos,nil);
  if reg=nil then begin
    CompileError;
    exit;
  end;
  extra := pcre_study(compiled,0,@errMsg);

  // now use the compiled pcre expression (once compiled, it is better to re-use compiled/extra values)
  found := pcre_exec(compiled,extra,pointer(text),StrLen(text),0,PCRE_NO_UTF8_CHECK,nil,0)>=0;

  // do not forget to release the compiled pcre expression
  pcre_dispose(compiled,extra,nil);

このコードは (およびUTF-8 へのTRegEx変換)よりもはるかに高速であり、で定義されているとおりです(これは設定されていないため、非常に低速です)。stringTPerlRegExRegularExpressionsCore.pasPCRE_NO_UTF8_CHECK

上記のサンプルの元のコードは、SQLite3 unitの REGEXP 演算子にあります

于 2013-10-10T06:15:57.540 に答える