Delphi-提取标记之间的字符串(重复标记)
我正在尝试编写一个函数来提取两个标记之间的字符串。 问题是,第一个标记在该字符串中是重复的,并且计数未知,例如Delphi-提取标记之间的字符串(重复标记),delphi,Delphi,我正在尝试编写一个函数来提取两个标记之间的字符串。 问题是,第一个标记在该字符串中是重复的,并且计数未知,例如 Str := 'Delphi App Hello Hello SomeText here Hello Hello Hello This is a Test!'; 我想要的是extract你好,这是一个测试 TagF是最后一个问候词 TagL是测试 TagF的重复计数是随机的 Function sExtractBetweenTagsB(Const s, LastTag, First
Str := 'Delphi App Hello Hello SomeText here Hello Hello Hello This is a Test!';
我想要的是extract你好,这是一个测试强>
- TagF是最后一个问候词
- TagL是测试李>
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!
您可以使用该函数扫描字符串以查找标记并向前搜索:
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.
输出:
Hello This is a Test
最简单的方法是使用正则表达式:
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.
这里是正则表达式
- (你好(?!你好)
--在字符串后面匹配“Hello”而不匹配“Hello”的实例(贪婪的前瞻) - *?
--懒惰匹配任何东西 - 测试!)
--匹配“测试!”
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;
尝试使用
lastdimiter
function@Mbo:虽然方便,但我宁愿使用32位的PosEx
,因为它有一个快速代码优化,而lastdimiter
没有。如果最后一个标记后面有第一个标记,则不起作用。@LURD嗯,要求不是很清楚,是吗?如果我正确理解了OP,则提取从最后一个起始标记开始。如果之后没有结束标记,那么结果应该是空的,不是吗?
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;