Pcre使用小记(三)自定义替换
Pcre有个函数是function Replace(const Input : string;const Replacement : string):来实现替换功能,
但是这个函数并不能完成我们所有的需求。我们都知道大多数情况下,使用Pcre匹配到的都是不定内容(如果你
一定要它匹配某个字符,算我没说,那还不如直接使用Pos),对于匹配到的内容进行替换,当然可以使用上面的
函数进行固定替换。但是我们更希望根据匹配到的内容进行一种可以定义替换结果的替换方法,我下面以匹配[A-Za-z]
所有英文字母进行首字母大写转换作为示例:
我们使用以下函数:
function TRegex.Replace(const Input: string; Evaluator: TRegexMatchEvaluator; MatchOptions : TRegMatchOptions): string;
其中TRegexMatchEvaluator是个返回String结果的函数,声明为:TRegexMatchEvaluator = function(theMatch: IMatch): string
我们看下这个替换函数的函数体:
function TRegex.Replace(const Input: string; Evaluator: TRegexMatchEvaluator; MatchOptions : TRegMatchOptions): string;
var
theOffset : Integer;
theToken : string;
theMatch : IMatch;
firstPosition : Integer;
lastPosition : Integer;
begin
if not Assigned(Evaluator) then
begin
Result := Input;
Exit;
end;
Result := '';
theOffset := 0;
firstPosition := 0;
theMatch := Match(Input, theOffset, MatchOptions);
while theMatch.Matched do
begin
lastPosition := theMatch.Index;
theToken := System.Copy(Input, firstPosition + 1, lastPosition - firstPosition);
if Length(theToken) <> 0 then
Result := Result + theToken;
Result := Result + Evaluator(theMatch);
firstPosition := theMatch.Index + theMatch.Length;
theOffset := Max(firstPosition, theMatch.Index + 1);
theMatch := Match(Input, theOffset, MatchOptions);
end;
theToken := System.Copy(Input, firstPosition + 1, MaxInt);
if Length(theToken) <> 0 then
Result := Result + theToken;
end;
那么我们的自定义替换其实就是给这个函数传个自己实现的TRegexMatchEvaluator而已
function ConvertCase(theMatch: IMatch): AnsiString;
begin
Result := theMatch.Groups[0].Value;
Result := AnsiTitleCase(Result);//实现首字母大写功能
end;
function textConvertCaseByfow(const S:AnsiString):AnsiString;
const
thePattern = '[a-zA-Z]+';
var
Regex: IRegex;
begin
Result:=S;
Regex := RegexCreate(thePattern);
Result :Regex.Replace(Result,ConvertCase,[]);
end;