OSDN Git Service

正規表現検索絡みの不具合対処 BRegExp.pasの最新版への更新
authorC.Ponapalt <ponapalt@shillest.net>
Thu, 11 Mar 2004 06:15:53 +0000 (06:15 +0000)
committerC.Ponapalt <ponapalt@shillest.net>
Thu, 11 Mar 2004 06:15:53 +0000 (06:15 +0000)
bottleclient/BRegExp.pas
bottleclient/LogForm.pas

index 8e9ae3d..02640db 100755 (executable)
@@ -2,7 +2,7 @@ unit BRegExp;
 
 //=====================================================================
 // BRegExp.pas : Borland Delphi \97p BREGEXP.DLL \97\98\97p\83\86\83j\83b\83g
-//               1998/10/11\94Å      osamu@big.or.jp
+//               1998/10/03\94Å      osamu@big.or.jp
 //
 // BREGEXP.DLL \82Í\81Ahttp://www.hi-ho.or.jp/~babaq/ \82É\82Ä\8cö\8aJ\82³\82ê\82Ä\82¢\82é
 // Perl5\8cÝ\8a·\82Ì\90³\8bK\95\\8c»\83G\83\93\83W\83\93 BREGEXP.DLL \82ð Borland Delphi \82©\82ç\97\98\97p
@@ -24,11 +24,14 @@ unit BRegExp;
 // \82¨\92m\82ç\82¹\89º\82³\82ê\82Î\81A\8bC\95ª\8e\9f\91æ\82Å\82Í\82È\82ñ\82ç\82©\82Ì\91Î\8f\88\82ð\82·\82é\89Â\94\\90«\82ª\82 \82è\82Ü\82·\81B(^_^;
 //
 // \8eg\97p\95û\96@\82É\82Â\82¢\82Ä\82Í\95t\91®\82Ì\83w\83\8b\83v\83t\83@\83C\83\8b\82ð\82²\97\97\89º\82³\82¢\81B
-//
-// [\97\9a\97ð]
-//  98.10.3     \8f\89\8aú\83o\81[\83W\83\87\83\93
-//  98.10.11    \83o\83O\83t\83B\83b\83N\83X (TBRegExpRec.splitp \82ð ^PChar -> PPChar)
-//
+//=====================================================================
+//               2001/04/14\94Å      osamu@big.or.jp
+// \96{\89Æ\82Ì\83h\83L\83\85\83\81\83\93\83g\82Ì\83o\81[\83W\83\87\83\93\83A\83b\83v\82É\94º\82¢\94­\8ao\82µ\82Ä\82¢\82½\83o\83O\82ð\8fC\90³
+// brx \8aÖ\90\94\82ð\93±\93ü
+// \8bó\95\8e\9a\82É\91Î\82·\82é\8c\9f\8dõ\82Ì\83G\83\89\81[\89ñ\94ð
+// MatchPos \82ð 1 \82©\82ç\90\94\82¦\8en\82ß\82é\82æ\82¤\82É\8ed\97l\95Ï\8dX
+// Subst \8cã\82É Strings[] \82ð\8eQ\8fÆ\89Â\94\\82É\82µ\82½
+// \82±\82ê\82É\94º\82¢\91å\97Ê\82Ì\95\8e\9a\97ñ\82É\91Î\82·\82é\92u\82«\8a·\82¦\93®\8dì\82Í\92x\82­\82È\82Á\82½
 //=====================================================================
 
 interface
@@ -40,9 +43,12 @@ uses SysUtils;
 // BREGEXP.DLL \82Æ\92¼\8c\8b\82µ\82½\90é\8c¾
 //=====================================================================
 
+const
+BREGEXP_ERROR_MAX= 80;  // \83G\83\89\81[\83\81\83b\83Z\81[\83W\82Ì\8dÅ\91å\92·
+
 type
 PPChar=^PChar;
-TBRegExpRec=record
+TBRegExpRec=packed record
     outp: PChar;        // \92u\8a·\82¦\8c\8b\89Ê\90æ\93ª\83|\83C\83\93\83^
     outendp: PChar;     // \92u\8a·\82¦\8c\8b\89Ê\96\96\94ö\83|\83C\83\93\83^
     splitctr: Integer;  // split \8c\8b\89Ê\83J\83E\83\93\83^
@@ -53,6 +59,7 @@ TBRegExpRec=record
     transtblp: PChar;   // tr \83e\81[\83u\83\8b\82Ö\82Ì\83|\83C\83\93\83^
     startp: PPChar;     // \83}\83b\83`\82µ\82½\95\8e\9a\97ñ\82Ö\82Ì\90æ\93ª\83|\83C\83\93\83^
     endp: PPChar;       // \83}\83b\83`\82µ\82½\95\8e\9a\97ñ\82Ö\82Ì\96\96\94ö\83|\83C\83\93\83^
+    nparens: Integer;   // match/subst \92\86\82Ì\8a\87\8cÊ\82Ì\90\94
 end;
 pTBRegExpRec=^TBRegExpRec;
 
@@ -83,30 +90,53 @@ TBRegExpMode=(brxNone, brxMatch, brxSplit);
 TBRegExp=class(TObject)
   private
     Mode: TBRegExpMode;
+    pTargetString: PChar;
     pBRegExp: PTBRegExpRec;
+    function GetMatchPos: Integer;
+    function GetMatchLength: Integer;
     function GetSplitCount: Integer;
     function GetSplitStrings(index: Integer): string;
     function GetMatchStrings(index:Integer): string;
     function GetMatchCount: Integer;
     function GetCount: Integer;
     function GetStrings(index: Integer): string;
+    function GetLastCommand: string;
+    procedure CheckCommand(const Command: string);
   public
     destructor Destroy; override;
   public
     function Match(const Command, TargetString: string): Boolean;
-    function Subst(const Command: string;var TargetString: string): Boolean;
+    function Subst(const Command: string; var TargetString: string): Boolean;
     function Split(const Command, TargetString: string; Limit: Integer): Boolean;
     function Trans(const Command: string;var TargetString: string): Boolean;
+    property LastCommand: string read GetLastCommand;
+    property MatchPos: Integer read GetMatchPos;
+    property MatchLength: Integer read GetMatchLength;
     property Count: Integer read GetCount;
     property Strings[index: Integer]: string read GetStrings; default;
 end;
 
 //=====================================================================
+// \8e©\93®\93I\82É\8eÀ\91Ì\89»\81A\94j\8aü\82³\82ê\82é\83\86\81[\83e\83B\83\8a\83e\83B\83C\83\93\83X\83^\83\93\83X
+//=====================================================================
+
+function brx: TBRegExp;
+
+//=====================================================================
 
 implementation
 
 //=====================================================================
 
+var fbrx: TBRegExp;
+function brx: TBRegExp;
+begin
+    if fbrx=nil then fbrx:=TBRegExp.Create;
+    Result:=fbrx;
+end;
+
+//=====================================================================
+
 destructor TBRegExp.Destroy;
 begin
     if pBRegExp<>nil then
@@ -115,31 +145,87 @@ begin
 end;
 
 //=====================================================================
+// \91O\89ñ\82Ì\83R\83}\83\93\83h\95\8e\9a\97ñ\82ð\95Ô\82·
+
+function TBRegExp.GetLastCommand: string;
+var len: Integer;
+begin
+    if pBRegExp=nil then begin
+        Result:= '';
+    end else begin
+        len:= Integer(pBRegExp^.paraendp)-Integer(pBRegExp^.parap);
+        SetLength(Result, len);
+        Move(pBRegExp^.parap^, Result[1], len);
+    end;
+end;
+
+//=====================================================================
+// \91O\89ñ\82Æ\88Ù\82È\82é\83R\83}\83\93\83h\82Å\82 \82ê\82Î\83L\83\83\83b\83V\83\85\82ð\83N\83\8a\83A\82·\82é\93à\95\94\8eè\91±\82«
+
+procedure TBRegExp.CheckCommand(const Command: string);
+var p,q: PChar;
+begin
+    if pBRegExp=nil then Exit;
+    p:= pBRegExp.parap - 1;
+    q:= PChar(@Command[1]) - 1;
+    repeat
+        Inc(p);
+        Inc(q);
+        if p^<>q^ then begin
+            BRegFree(pBRegExp);
+            pBRegExp:= nil;
+            Break;
+        end;
+    until p^=#0;
+end;
+
+//=====================================================================
 
 function TBRegExp.Match(const Command, TargetString: string): Boolean;
 var ErrorString: string;
+    i: Integer;
 begin
-    SetLength(ErrorString,256);
+    CheckCommand(Command);
+    SetLength(ErrorString, BREGEXP_ERROR_MAX);
     Mode:=brxNone;
-    Result:=BMatch(
-        PChar(Command),
-        PChar(TargetString),
-        PChar(TargetString)+Length(TargetString),
-        pBRegExp,
-        PChar(ErrorString));
-    SetLength(ErrorString,StrLen(PChar(ErrorString)));
+    if TargetString='' then begin // \83G\83\89\81[\89ñ\94ð
+        i:=0;
+        Result:=BMatch(
+            PChar(Command),
+            PChar(@i),
+            PChar(@i)+1,    
+            pBRegExp,
+            PChar(ErrorString));
+    end else begin
+        Result:=BMatch(
+            PChar(Command),
+            PChar(TargetString),
+            PChar(TargetString)+Length(TargetString),
+            pBRegExp,
+            PChar(ErrorString));
+    end;
+    SetLength(ErrorString, StrLen(PChar(ErrorString)));
     if ErrorString<>'' then
         raise EBRegExpError.Create(ErrorString);
-    Mode:=brxMatch;
+    if Result then Mode:= brxMatch;
+    pTargetString:= PChar(TargetString);
 end;
 
 //=====================================================================
 
 function TBRegExp.Subst(const Command: string;
                         var TargetString: string): Boolean;
+const TextBuffer: string='';
 var ErrorString: string;
+    ep,sp: PPChar;
+    i: Integer;
 begin
-    SetLength(ErrorString,256);
+    CheckCommand(Command);
+    Result:=False;
+    if TargetString='' then Exit;
+    TextBuffer:= TargetString;  // ( ) \82ð\90³\82µ\82­\95Ô\82·\82½\82ß\82É\83e\83L\83X\83g\82ð\95Û\91\82·\82é
+    UniqueString(TextBuffer);
+    SetLength(ErrorString, BREGEXP_ERROR_MAX);
     Mode:=brxNone;
     Result:=BSubst(
         PChar(Command),
@@ -148,9 +234,21 @@ begin
         pBRegExp,
         PChar(ErrorString));
     SetLength(ErrorString,StrLen(PChar(ErrorString)));
-    if ErrorString<>'' then
+    if ErrorString<>'' then 
         raise EBRegExpError.Create(ErrorString);
-    if Result then TargetString:=pBRegExp^.outp;
+
+    if Result then begin // ( ) \82Ì\8c\8b\89Ê\82ð\90³\82µ\82­\95Ô\82·\82½\82ß
+        sp:=pBRegExp^.startp;
+        ep:=pBRegExp^.endp;
+        for i:=0 to GetMatchCount-1 do begin
+            Inc(ep^, Integer(TextBuffer)-Integer(TargetString));
+            Inc(sp^, Integer(TextBuffer)-Integer(TargetString));
+            Inc(sp);
+            Inc(ep);
+        end;
+        TargetString:= pBRegExp^.outp;
+        Mode:=brxMatch;
+    end;
 end;
 
 //=====================================================================
@@ -159,8 +257,11 @@ function TBRegExp.Trans(const Command: string;
                         var TargetString: string): Boolean;
 var ErrorString: string;
 begin
-    SetLength(ErrorString,256);
+    CheckCommand(Command);
     Mode:=brxNone;
+    if TargetString='' then // \83G\83\89\81[\89ñ\94ð
+        TargetString:= #0;
+    SetLength(ErrorString, BREGEXP_ERROR_MAX);
     Result:=BTrans(
         PChar(Command),
         PChar(TargetString),
@@ -178,16 +279,29 @@ end;
 function TBRegExp.Split(const Command, TargetString: string;
                         Limit: Integer): Boolean;
 var ErrorString: string;
+    t: string;
 begin
-    SetLength(ErrorString,256);
+    CheckCommand(Command);
+    SetLength(ErrorString, BREGEXP_ERROR_MAX);
     Mode:=brxNone;
-    Result:=BSplit(
-        PChar(Command),
-        PChar(TargetString),
-        PChar(TargetString)+Length(TargetString),
-        Limit,
-        pBRegExp,
-        PChar(ErrorString));
+    if TargetString='' then begin // \83G\83\89\81[\89ñ\94ð
+        t:= #0;
+        Result:=BSplit(
+            PChar(Command),
+            PChar(t),
+            PChar(t)+1,
+            Limit,
+            pBRegExp,
+            PChar(ErrorString));
+    end else begin
+        Result:=BSplit(
+            PChar(Command),
+            PChar(TargetString),
+            PChar(TargetString)+Length(TargetString),
+            Limit,
+            pBRegExp,
+            PChar(ErrorString));
+    end;
     SetLength(ErrorString,StrLen(PChar(ErrorString)));
     if ErrorString<>'' then
         raise EBRegExpError.Create(ErrorString);
@@ -196,6 +310,24 @@ end;
 
 //=====================================================================
 
+function TBRegExp.GetMatchPos: Integer;
+begin
+    if Mode<>brxMatch then
+        raise EBRegExpError.Create('no match pos');
+    Result:=Integer(pBRegExp.startp^)-Integer(pTargetString)+1;
+end;
+
+//=====================================================================
+
+function TBRegExp.GetMatchLength: Integer;
+begin
+    if Mode<>brxMatch then
+        raise EBRegExpError.Create('no match length');
+    Result:=Integer(pBRegExp.endp^)-Integer(pBRegExp.startp^);
+end;
+
+//=====================================================================
+
 function TBRegExp.GetCount: Integer;
 begin
     Result:=0;
@@ -209,19 +341,15 @@ begin
     end;
 end;
 
+//=====================================================================
+
 function TBRegExp.GetMatchCount: Integer;
-var sp,ep: PPChar;
 begin
-    Result:=0;
-    sp:=pBRegExp^.startp;
-    ep:=pBRegExp^.endp;
-    while Integer(sp^)<Integer(ep^) do begin
-        Inc(sp);
-        Inc(ep);
-        Inc(Result);
-    end;
+    Result:= pBRegExp^.nparens+1;
 end;
 
+//=====================================================================
+
 function TBRegExp.GetSplitCount: Integer;
 begin
     Result:=pBRegExp^.splitctr;
@@ -242,23 +370,22 @@ begin
     end;
 end;
 
+//=====================================================================
+
 function TBRegExp.GetMatchStrings(index:Integer):string;
 var sp,ep: PPChar;
 begin
     Result:='';
-    sp:=pBRegExp^.startp;
-    ep:=pBRegExp^.endp;
-    while index>0 do begin
-        if Integer(sp^)>=Integer(ep^) then
-            raise EBRegExpError.Create('index out of range');
-        Inc(sp);
-        Inc(ep);
-        Dec(index);
-    end;
+    if (index<0) or (index>=GetMatchCount) then
+        raise EBRegExpError.Create('index out of range');
+    sp:=pBRegExp^.startp; Inc(sp, index);
+    ep:=pBRegExp^.endp;   Inc(ep, index);
     SetLength(Result,Integer(ep^)-Integer(sp^));
     Move(sp^^,PChar(Result)^,Integer(ep^)-Integer(sp^));
 end;
 
+//=====================================================================
+
 function TBRegExp.GetSplitStrings(index:Integer): string;
 var p: PPChar;
     sp,ep: PChar;
@@ -266,15 +393,16 @@ begin
     if (index<0) or (index>=GetSplitCount) then
         raise EBRegExpError.Create('index out of range');
     p:=pBRegExp^.splitp;
-    Inc(p,index*2);
-    sp:=p^;
-    Inc(p);
-    ep:=p^;
+    Inc(p,index*2); sp:=p^;
+    Inc(p);         ep:=p^;
     SetLength(Result,Integer(ep)-Integer(sp));
     Move(sp^,PChar(Result)^,Integer(ep)-Integer(sp));
 end;
 
 //=====================================================================
 
+initialization
+finalization
+    fbrx.Free;
 end.
 
index f3dd8f1..67c0d9f 100755 (executable)
@@ -1672,7 +1672,8 @@ begin
           if not RegExp.Match(Condition.ScriptPattern, Bottle.Script) then
             Ok := false;
         except
-          on EBRegExpError do ; // do nothing
+          on EBRegExpError do
+            Ok := false; //\96­\82È\90³\8bK\95\\8c»\82ð\8fR\82é
         end;
       end else
       begin