Delphi 通过子字符串搜索比较 2 个字符串列表并将匹配项合并到另一个字符串列表中
Delphi compare 2 stringlists by substring search and merge the matching items in another stringlist
我正在尝试通过子字符串搜索来比较 2 个字符串列表,并将找到的项目匹配到另一个字符串列表中。
"Stringlist_SCSILogicalUnit" 包含如下数据:
SCSIBus=0;SCSILogicalUnit=0;SCSIPort=1;SCSITargetId=0;Status=OK
SCSIBus=0;SCSILogicalUnit=1;SCSIPort=2;SCSITargetId=0;Status=OK
SCSIBus=0;SCSILogicalUnit=2;SCSIPort=2;SCSITargetId=0;Status=OK
SCSIBus=0;SCSILogicalUnit=3;SCSIPort=2;SCSITargetId=0;Status=OK
SCSIBus=0;SCSILogicalUnit=4;SCSIPort=2;SCSITargetId=0;Status=OK
SCSIBus=0;SCSILogicalUnit=43;SCSIPort=2;SCSITargetId=0;Status=OK
SCSIBus=0;SCSILogicalUnit=44;SCSIPort=2;SCSITargetId=0;Status=OK
SCSIBus=0;SCSILogicalUnit=45;SCSIPort=2;SCSITargetId=0;Status=OK
SCSIBus=0;SCSILogicalUnit=46;SCSIPort=2;SCSITargetId=0;Status=OK
"Stringlist_LUN" 包含如下数据:
LocationInformation REG_SZ Port(2,2,3,3) Bus 0, Target ID 0, LUN 67
;
LocationInformation REG_SZ Port(2,2,3,3) Bus 0, Target ID 0, LUN 43
;
LocationInformation REG_SZ Port(2,2,3,3) Bus 0, Target ID 0, LUN 44
;
LocationInformation REG_SZ Port(2,2,3,3) Bus 0, Target ID 0, LUN 45
;
LocationInformation REG_SZ Port(2,2,3,3) Bus 0, Target ID 0, LUN 50
;
LocationInformation REG_SZ Port(2,2,3,3) Bus 0, Target ID 0, LUN 51
;
我需要匹配"LUN"值和"SCSILogicalUnit"值之间的对应关系(LUN和SCSILogicalUnit具有相同的值Lun=SCSILogicalUnit)以便在"Stringlist_result"中监听结果.
结果应该像
"SCSIBus=0;SCSILogicalUnit=46;SCSIPort=2;SCSITargetId=0;Status=OK =>>> LocationInformation REG_SZ Port(2,2,3,3) Bus 0, Target ID 0, LUN 46
;"
我正在使用以下函数,但结果不一致:
function stringlist_mmg_FastJoin(List1, List2: TStringList): TStringList;
var
L1Idx, L2Idx,
L1Max, L2Max: Integer;
v: Integer;
begin
// Create Result list, set it's min size
Result := TStringList.Create;
Result.Capacity := Max(List1.Count, List2.Count);
// limits
L1Idx := 0;
L2Idx := 0;
L1Max := List1.Count;
L2Max := List2.Count;
// forse sort
List1.Sorted := True;
List2.Sorted := True;
// iterate
while (L1Idx<L1Max) and (L2Idx<L2Max) do
begin
if pos(extracttextbetween(List1[L1idx],'SCSILogicalUnit=',';'),List2[L2idx])>1 then
begin
Result.Add(List1[L1Idx]+' = '+List2[L2idx]);
Inc(L1Idx);
Inc(L2Idx);
end
else if v < 0 then // Add from List 1
begin
//Result.Add(List1[L1Idx]);
Inc(L1Idx);
end
else // v > 0 // Add from List 2
begin
//Result.Add(List2[L2Idx]);
Inc(L2Idx);
end;
end;
// Add all remainders from second list
while L2Idx < L2Max do
begin
//Result.Add(List2[L2Idx]);
Inc(L2Idx);
end;
end;
stringlist_resultat:=Tstringlist.create;
stringlist_rezultat.addstrings(stringlist_mmg_FastJoin(Stringlist_SCSILogicalUnit,stringlist_LUN));
结果应该是:
PNPDeviceID=MPIOSCSIBus=0;SCSILogicalUnit=67;SCSIPort=2;SCSITargetId=0;Status=OK =>>> LocationInformation REG_SZ Port(2,2,3,3) Bus 0, Target ID 0, LUN 67
;
当我 运行 函数时,我得到一个结果。
有人可以告诉我我做错了什么吗?
没有字符串列表可以优化这个任务吗?
谢谢!
将其重命名为 just Join,不能声称其快速..
function stringlist_mmg_Join(const LogicalUnitList, LUNList: TStringList): TStringList;
const NotFound = -1;
function ExtractTextBetween(const Txt, StartTag, EndTag : string; out iValue : integer): Boolean;
var
value : string;
iStartTag, iEndTag : integer;
begin
Result := False;
iStartTag := Pos(StartTag, Txt);
if (iStartTag = NotFound) then Exit;
iEndTag := PosEx(EndTag, Txt, iStartTag);
if (iEndTag = NotFound) then Exit;
Inc(iStartTag, Length(StartTag));
Value := MidStr(Txt, iStartTag, iEndTag-iStartTag);
Result := TryStrToInt(Value, iValue);
end;
var
i, v, ix: Integer;
begin
Result := TStringList.Create;
// iterate, Parse and write Value as Object
for i := 0 to LogicalUnitList.Count - 1 do begin
If ExtractTextBetween(LogicalUnitList[i], 'SCSILogicalUnit=', ';', v) then begin
LogicalUnitList.Objects[i] := Pointer(V+1);
end;
end;
// iterate, Parse and write Value as Object
for i := 0 to LUNList.Count - 1 do begin
If ExtractTextBetween(LUNList[i] + ';', 'LUN ', ';', v) then begin
LUNList.Objects[i] := Pointer(V+1);
end;
end;
// Match
for i := 0 to LogicalUnitList.Count - 1 do begin
ix := LUNList.IndexOfObject(LogicalUnitList.Objects[i]);
if (ix = NotFound) then Continue;
Result.Add(LogicalUnitList[i] + ' =>>>' + LUNList[ix] + ';');
end;
end;
输出为:
SCSIBus=0;SCSILogicalUnit=43;SCSIPort=2;SCSITargetId=0;Status=OK =>>> LocationInformation REG_SZ Port(2,2,3,3) Bus 0, Target ID 0, LUN 43;
SCSIBus=0;SCSILogicalUnit=44;SCSIPort=2;SCSITargetId=0;Status=OK =>>> LocationInformation REG_SZ Port(2,2,3,3) Bus 0, Target ID 0, LUN 44;
SCSIBus=0;SCSILogicalUnit=45;SCSIPort=2;SCSITargetId=0;Status=OK =>>> LocationInformation REG_SZ Port(2,2,3,3) Bus 0, Target ID 0, LUN 45;
我正在尝试通过子字符串搜索来比较 2 个字符串列表,并将找到的项目匹配到另一个字符串列表中。
"Stringlist_SCSILogicalUnit" 包含如下数据:
SCSIBus=0;SCSILogicalUnit=0;SCSIPort=1;SCSITargetId=0;Status=OK
SCSIBus=0;SCSILogicalUnit=1;SCSIPort=2;SCSITargetId=0;Status=OK
SCSIBus=0;SCSILogicalUnit=2;SCSIPort=2;SCSITargetId=0;Status=OK
SCSIBus=0;SCSILogicalUnit=3;SCSIPort=2;SCSITargetId=0;Status=OK
SCSIBus=0;SCSILogicalUnit=4;SCSIPort=2;SCSITargetId=0;Status=OK
SCSIBus=0;SCSILogicalUnit=43;SCSIPort=2;SCSITargetId=0;Status=OK
SCSIBus=0;SCSILogicalUnit=44;SCSIPort=2;SCSITargetId=0;Status=OK
SCSIBus=0;SCSILogicalUnit=45;SCSIPort=2;SCSITargetId=0;Status=OK
SCSIBus=0;SCSILogicalUnit=46;SCSIPort=2;SCSITargetId=0;Status=OK
"Stringlist_LUN" 包含如下数据:
LocationInformation REG_SZ Port(2,2,3,3) Bus 0, Target ID 0, LUN 67
;
LocationInformation REG_SZ Port(2,2,3,3) Bus 0, Target ID 0, LUN 43
;
LocationInformation REG_SZ Port(2,2,3,3) Bus 0, Target ID 0, LUN 44
;
LocationInformation REG_SZ Port(2,2,3,3) Bus 0, Target ID 0, LUN 45
;
LocationInformation REG_SZ Port(2,2,3,3) Bus 0, Target ID 0, LUN 50
;
LocationInformation REG_SZ Port(2,2,3,3) Bus 0, Target ID 0, LUN 51
;
我需要匹配"LUN"值和"SCSILogicalUnit"值之间的对应关系(LUN和SCSILogicalUnit具有相同的值Lun=SCSILogicalUnit)以便在"Stringlist_result"中监听结果. 结果应该像
"SCSIBus=0;SCSILogicalUnit=46;SCSIPort=2;SCSITargetId=0;Status=OK =>>> LocationInformation REG_SZ Port(2,2,3,3) Bus 0, Target ID 0, LUN 46
;"
我正在使用以下函数,但结果不一致:
function stringlist_mmg_FastJoin(List1, List2: TStringList): TStringList;
var
L1Idx, L2Idx,
L1Max, L2Max: Integer;
v: Integer;
begin
// Create Result list, set it's min size
Result := TStringList.Create;
Result.Capacity := Max(List1.Count, List2.Count);
// limits
L1Idx := 0;
L2Idx := 0;
L1Max := List1.Count;
L2Max := List2.Count;
// forse sort
List1.Sorted := True;
List2.Sorted := True;
// iterate
while (L1Idx<L1Max) and (L2Idx<L2Max) do
begin
if pos(extracttextbetween(List1[L1idx],'SCSILogicalUnit=',';'),List2[L2idx])>1 then
begin
Result.Add(List1[L1Idx]+' = '+List2[L2idx]);
Inc(L1Idx);
Inc(L2Idx);
end
else if v < 0 then // Add from List 1
begin
//Result.Add(List1[L1Idx]);
Inc(L1Idx);
end
else // v > 0 // Add from List 2
begin
//Result.Add(List2[L2Idx]);
Inc(L2Idx);
end;
end;
// Add all remainders from second list
while L2Idx < L2Max do
begin
//Result.Add(List2[L2Idx]);
Inc(L2Idx);
end;
end;
stringlist_resultat:=Tstringlist.create;
stringlist_rezultat.addstrings(stringlist_mmg_FastJoin(Stringlist_SCSILogicalUnit,stringlist_LUN));
结果应该是:
PNPDeviceID=MPIOSCSIBus=0;SCSILogicalUnit=67;SCSIPort=2;SCSITargetId=0;Status=OK =>>> LocationInformation REG_SZ Port(2,2,3,3) Bus 0, Target ID 0, LUN 67
;
当我 运行 函数时,我得到一个结果。
有人可以告诉我我做错了什么吗? 没有字符串列表可以优化这个任务吗?
谢谢!
将其重命名为 just Join,不能声称其快速..
function stringlist_mmg_Join(const LogicalUnitList, LUNList: TStringList): TStringList;
const NotFound = -1;
function ExtractTextBetween(const Txt, StartTag, EndTag : string; out iValue : integer): Boolean;
var
value : string;
iStartTag, iEndTag : integer;
begin
Result := False;
iStartTag := Pos(StartTag, Txt);
if (iStartTag = NotFound) then Exit;
iEndTag := PosEx(EndTag, Txt, iStartTag);
if (iEndTag = NotFound) then Exit;
Inc(iStartTag, Length(StartTag));
Value := MidStr(Txt, iStartTag, iEndTag-iStartTag);
Result := TryStrToInt(Value, iValue);
end;
var
i, v, ix: Integer;
begin
Result := TStringList.Create;
// iterate, Parse and write Value as Object
for i := 0 to LogicalUnitList.Count - 1 do begin
If ExtractTextBetween(LogicalUnitList[i], 'SCSILogicalUnit=', ';', v) then begin
LogicalUnitList.Objects[i] := Pointer(V+1);
end;
end;
// iterate, Parse and write Value as Object
for i := 0 to LUNList.Count - 1 do begin
If ExtractTextBetween(LUNList[i] + ';', 'LUN ', ';', v) then begin
LUNList.Objects[i] := Pointer(V+1);
end;
end;
// Match
for i := 0 to LogicalUnitList.Count - 1 do begin
ix := LUNList.IndexOfObject(LogicalUnitList.Objects[i]);
if (ix = NotFound) then Continue;
Result.Add(LogicalUnitList[i] + ' =>>>' + LUNList[ix] + ';');
end;
end;
输出为:
SCSIBus=0;SCSILogicalUnit=43;SCSIPort=2;SCSITargetId=0;Status=OK =>>> LocationInformation REG_SZ Port(2,2,3,3) Bus 0, Target ID 0, LUN 43;
SCSIBus=0;SCSILogicalUnit=44;SCSIPort=2;SCSITargetId=0;Status=OK =>>> LocationInformation REG_SZ Port(2,2,3,3) Bus 0, Target ID 0, LUN 44;
SCSIBus=0;SCSILogicalUnit=45;SCSIPort=2;SCSITargetId=0;Status=OK =>>> LocationInformation REG_SZ Port(2,2,3,3) Bus 0, Target ID 0, LUN 45;