我试图编写一个函数来提取两个标记之间的字符串。 问题是第一个标签是该字符串中的副本,具有未知计数,例如
Str := 'Delphi App Hello Hello SomeText here Hello Hello Hello This is a Test!';
我想要的是提取 你好这是一个测试!
TagF的重复计数随机。
Function sExtractBetweenTagsB(Const s, LastTag, FirstTag: string): string;
var
i, f : integer;
sTemp : string;
begin
sTemp := s;
repeat
Delete(sTemp,Pos(FirstTag, sTemp),length(FirstTag));
until AnsiPos(FirstTag,sTemp) = 0;
f := Pos(LastTag, sTemp);
Result:= FirstTag+' '+Copy(sTemp, 1, length(sTemp));
end;
输出结果为:
Hello Delphi App SomeText here This is a Test!
答案 0 :(得分:4)
您可以使用PosEx
功能扫描字符串中的标记并向前搜索:
program SO30827180;
{$APPTYPE CONSOLE}
{$R *.res}
uses
SysUtils,
StrUtils;
function ExtractString(const Input : String; const TagF: String; const TagL : String) : String;
var
LastPos : Integer;
NewPos : Integer;
begin
Result := '';
NewPos := Pos(TagF, Input);
if NewPos <> 0 then
begin
LastPos := NewPos;
// scan to last start tag
while true do
begin
NewPos := PosEx(TagF, Input, NewPos+1);
if NewPos <> 0 then
LastPos := NewPos
else
Break;
end;
// now seek end tag, starting from last starting tag position
NewPos := PosEx(TagL, Input, LastPos+1);
if NewPos <> 0 then
Result := Copy(Input, LastPos, NewPos-LastPos+Length(TagL));
end;
end;
var
Line : String;
begin
Line := 'Delphi App Hello Hello SomeText here Hello Hello Hello This is a Test!';
Writeln(Format('Input: "%s"', [Line]));
Writeln(Format('Ouput: "%s"', [ExtractString(Line, 'Hello', 'Test!')]));
Line := ' Test! Delphi App Hello Hello SomeText here Hello Hello Hello This is a Test! Some end chars';
Writeln(Format('Input: "%s"', [Line]));
Writeln(Format('Ouput: "%s"', [ExtractString(Line, 'Hello', 'Test!')]));
Readln;
end.
示例输出:
Input: "Delphi App Hello Hello SomeText here Hello Hello Hello This is a Test!"
Ouput: "Hello This is a Test!"
Input: " Test! Delphi App Hello Hello SomeText here Hello Hello Hello This is a Test! Some end chars"
Ouput: "Hello This is a Test!"
答案 1 :(得分:2)
Function sExtractBetweenTagsB(Const s, LastTag, FirstTag: string): string;
var
pLast,pFirst,pNextFirst : Integer;
begin
pFirst := Pos(FirstTag,s);
pLast := Pos(LastTag,s);
while (pLast > 0) and (pFirst > 0) do begin
if (pFirst > pLast) then // Find next LastTag
pLast := PosEx(LastTag,s,pLast+Length(LastTag))
else
begin
pNextFirst := PosEx(FirstTag,s,pFirst+Length(FirstTag));
if (pNextFirst = 0) or (pNextFirst > pLast) then begin
Result := Copy(s,pFirst,pLast-pFirst+Length(LastTag));
Exit;
end
else
pFirst := pNextFirst;
end;
end;
Result := '';
end;
var
s: String;
begin
s := 'Delphi App Hello Hello SomeText here Hello Hello Hello This is a Test! Hello';
WriteLn(sExtractBetweenTagsB(s,'Test','Hello'));
end.
输出:
Hello This is a Test
答案 2 :(得分:2)
最简单的方法是使用正则表达式:
program Project1;
{$APPTYPE CONSOLE}
uses
RegularExpressions;
var
regEx : TRegEx;
testString : string;
m : TMatch;
begin
testString := 'Delphi App Hello Hello SomeText here Hello Hello Hello This is a Test!';
regEx := TRegEx.Create('(Hello(?!.*Hello).*?Test!)');
m := regEx.Match(testString);
if m.Success then
WriteLn(m.Value)
else
WriteLn('No match.');
ReadLn;
end.
这里的正则表达式是
如果你想概括:
function ExtractBetweenTags(const s : string; FirstTag, LastTag : string) : string;
var
regEx : TRegEx;
begin
regEx := TRegEx.Create(Format('(%s(?!.*%s).*?%s)', [FirstTag, FirstTag, LastTag]));
result := regEx.Match(s).Value;
end;