//=====================================================================
// 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
// \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
// 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^
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;
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
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),
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;
//=====================================================================
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),
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);
//=====================================================================
+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;
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;
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;
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.