Delphi - 提取标签之间的字符串(重复标签)

时间:2015-06-14 08:04:39

标签: delphi

我试图编写一个函数来提取两个标记之间的字符串。 问题是第一个标签是该字符串中的副本,具有未知计数,例如

Str := 'Delphi App Hello Hello SomeText here Hello Hello Hello This is a Test!';

我想要的是提取 你好这是一个测试!

  • TagF是最后一个 Hello
  • TagL是测试!

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!

3 个答案:

答案 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.

这里的正则表达式是

  • (喂(?!。*你好)
    - 匹配&#34;你好&#34;没有&#34; Hello&#34;的实例后来在字符串中(贪婪的向前看)
  • 即可。*吗
    - 懒惰匹配任何东西
  • 测试!)
    - 匹配&#34;测试!&#34;

如果你想概括:

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;