program project1;
{$Mode objfpc}{$H+}
uses sysutils;
var
txt: String = '185.86.164.111 [13/Oct/2019:11:10:29 +0000] "GET /wp-login.php HTTP/1.1" 404 "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36"';
arr: TStringArray;
s: String;
type
TEnclosers = record
left, right: Char;
end;
TEnclosersArray = array of TEnclosers;
function SplitToArrayOK(const aTxt: String; enclosers: array of const; out StringArray: TStringArray; separator: Char = ' '): Boolean;
var
lefts: TSysCharSet = [];
rights: TSysCharSet = [];
match: Char = #0;
p, j, encsHigh: Integer;
encsArray: TEnclosersArray;
inEnclosure: Boolean = False;
function GetRightForLeft(aLeft: Char): Char;
var
i: Integer;
begin
for i := 0 to High(encsArray) do
if encsArray[i].left = aLeft then
Exit(encsArray[i].right);
Result := #0;
end;
begin
SetLength(StringArray{%H-}, 0);
SetLength(encsArray{%H-}, 0);
Result := False;
encsHigh := High(enclosers);
if (encsHigh = -1) or not Odd(encsHigh) then
Exit;
SetLength(encsArray, Length(enclosers) div 2);
j := 0;
for p := 0 to encsHigh do
begin
if enclosers[p].VType <> vtChar then
Exit;
case Odd(p) of
False:
begin
Include(lefts, enclosers[p].VChar);
encsArray[j].left := enclosers[p].VChar;
end;
True:
begin
Include(rights, enclosers[p].VChar);
encsArray[j].right := enclosers[p].VChar;
Inc(j);
end;
end;
end;
for p := 1 to Length(aTxt) do
case (aTxt[p] in lefts) of
True:
begin
case (match = #0) of
True:
begin
match := GetRightForLeft(aTxt[p]);
inEnclosure := True;
end;
False:
case (aTxt[p] in rights) of
True:
begin
match := #0;
inEnclosure := False;
end;
False: Exit;
end;
end;
end;
False:
begin
case (aTxt[p] in rights) of
True:
begin
case (aTxt[p] = match) of
True:
begin
match := #0;
inEnclosure := False;
end;
False: Exit;
end;
end;
False:
case inEnclosure of
True:
begin
if Length(StringArray) = 0 then
SetLength(StringArray, 1);
StringArray[High(StringArray)] += aTxt[p];
end;
False:
case (aTxt[p] = separator) of
True: SetLength(StringArray, Length(StringArray)+1);
False:
begin
if Length(StringArray) = 0 then
SetLength(StringArray, 1);
StringArray[High(StringArray)] += aTxt[p];
end;
end;
end;
end;
end;
end;
Result := True;
end;
begin
if SplitToArrayOK(txt, ['"','"','[',']'], arr) then
for s in arr do
WriteLn(s)
else Writeln('invalid data or parameters');
end.