如何从字符串列表中解析多行
How to parse multiples lines from StringList
我想从 StringList 复制特定的行,
我想将所有具有 'Domain Status:' 的行复制到 memo.lines.text
我使用了下面的代码,但问题是它只复制了第一行,我想复制所有具有 'Domain Status:':
的行
const
FieldNames: array[0..2] of string = ('Domain Status', 'domain status', 'Domain status');
begin
sl := TStringList.Create;
try
sl.Assign(Memo.Lines);
for I := 0 to sl.Count-1 do begin
sl[I] := TrimLeft(sl[I]);
end;
sl.NameValueSeparator := ':';
for I := Low(FieldNames) to High(FieldNames) do begin
status := Trim(sl.Values[FieldNames[I]]);
if status <> '' then Break;
end;
finally
sl.Free;
end;
memo1.lines.text:=status;
StringList 中的文本示例:
Domain Name: yahoo.com
Registry Domain ID: 3643624_DOMAIN_COM-VRSN
Registrar WHOIS Server: whois.markmonitor.com
Registrar URL: http://www.markmonitor.com
Updated Date: 2022-03-09T15:51:45+0000
Creation Date: 1995-01-18T08:00:00+0000
Registrar Registration Expiration Date: 2023-01-19T05:00:00+0000
Registrar: MarkMonitor, Inc.
Registrar IANA ID: 292
Registrar Abuse Contact Email: email@markmonitor.com
Registrar Abuse Contact Phone: +1.2083895770
Domain Status: clientUpdateProhibited (https://www.icann.org/epp#clientUpdateProhibited)
Domain Status: clientTransferProhibited (https://www.icann.org/epp#clientTransferProhibited)
Domain Status: clientDeleteProhibited (https://www.icann.org/epp#clientDeleteProhibited)
Domain Status: serverUpdateProhibited (https://www.icann.org/epp#serverUpdateProhibited)
Domain Status: serverTransferProhibited (https://www.icann.org/epp#serverTransferProhibited)
Domain Status: serverDeleteProhibited (https://www.icann.org/epp#serverDeleteProhibited)
Registrant Organization: Yahoo Assets LLC
Registrant State/Province: VA
我想得到:
clientUpdateProhibited
clientTransferProhibited
clientDeleteProhibited
serverUpdateProhibited
serverTransferProhibited
.....
without the http://www.icann.org...
您需要遍历 TStringList
的各个字符串,TStringList.Values[]
属性 不会帮助您完成此任务,因为它只会搜索第一个字符串一个匹配的名字。但是,您可以使用 TStringList.Names[]
和 TStringList.ValueFromIndex[]
属性来帮助您。
此外,您根本不需要 FieldNames[]
数组。使用 case-insensitive 比较,例如 SysUtils.SameText()
。
试试像这样的东西:
sl := TStringList.Create;
try
sl.Assign(Memo.Lines);
sl.NameValueSeparator := ':';
for I := 0 to sl.Count-1 do begin
sl[I] := TrimLeft(sl[I]);
if SameText(sl.Names[I], 'Domain Status') then begin
status := Trim(sl.ValueFromIndex[I]);
status := Copy(status, 1, Pos(' ', status)-1);
Memo1.Lines.Add(status);
end;
end;
finally
sl.Free;
end;
另一种方法是使用正则表达式。有点矫枉过正,但如果您可以保留正则表达式而不是每次使用都重新创建它,性能可以相提并论。
procedure TForm1.Button1Click(Sender: TObject);
Var
RegExDomainStatus : TRegEx;
Match : TMatch;
Alltext : string;
begin
RegExDomainStatus.Create('(?<=^domain status: )[A-z]+',[roIgnoreCase,roMultiline]);
Alltext := Memo1.Lines.Text;
Memo1.Lines.Clear;
match := RegExDomainStatus.Match(AllText);
while match.Success do
begin
memo1.Lines.add(match.Value);
match := match.NextMatch;
end;
end;
我想从 StringList 复制特定的行, 我想将所有具有 'Domain Status:' 的行复制到 memo.lines.text 我使用了下面的代码,但问题是它只复制了第一行,我想复制所有具有 'Domain Status:':
的行 const
FieldNames: array[0..2] of string = ('Domain Status', 'domain status', 'Domain status');
begin
sl := TStringList.Create;
try
sl.Assign(Memo.Lines);
for I := 0 to sl.Count-1 do begin
sl[I] := TrimLeft(sl[I]);
end;
sl.NameValueSeparator := ':';
for I := Low(FieldNames) to High(FieldNames) do begin
status := Trim(sl.Values[FieldNames[I]]);
if status <> '' then Break;
end;
finally
sl.Free;
end;
memo1.lines.text:=status;
StringList 中的文本示例:
Domain Name: yahoo.com
Registry Domain ID: 3643624_DOMAIN_COM-VRSN
Registrar WHOIS Server: whois.markmonitor.com
Registrar URL: http://www.markmonitor.com
Updated Date: 2022-03-09T15:51:45+0000
Creation Date: 1995-01-18T08:00:00+0000
Registrar Registration Expiration Date: 2023-01-19T05:00:00+0000
Registrar: MarkMonitor, Inc.
Registrar IANA ID: 292
Registrar Abuse Contact Email: email@markmonitor.com
Registrar Abuse Contact Phone: +1.2083895770
Domain Status: clientUpdateProhibited (https://www.icann.org/epp#clientUpdateProhibited)
Domain Status: clientTransferProhibited (https://www.icann.org/epp#clientTransferProhibited)
Domain Status: clientDeleteProhibited (https://www.icann.org/epp#clientDeleteProhibited)
Domain Status: serverUpdateProhibited (https://www.icann.org/epp#serverUpdateProhibited)
Domain Status: serverTransferProhibited (https://www.icann.org/epp#serverTransferProhibited)
Domain Status: serverDeleteProhibited (https://www.icann.org/epp#serverDeleteProhibited)
Registrant Organization: Yahoo Assets LLC
Registrant State/Province: VA
我想得到:
clientUpdateProhibited
clientTransferProhibited
clientDeleteProhibited
serverUpdateProhibited
serverTransferProhibited
.....
without the http://www.icann.org...
您需要遍历 TStringList
的各个字符串,TStringList.Values[]
属性 不会帮助您完成此任务,因为它只会搜索第一个字符串一个匹配的名字。但是,您可以使用 TStringList.Names[]
和 TStringList.ValueFromIndex[]
属性来帮助您。
此外,您根本不需要 FieldNames[]
数组。使用 case-insensitive 比较,例如 SysUtils.SameText()
。
试试像这样的东西:
sl := TStringList.Create;
try
sl.Assign(Memo.Lines);
sl.NameValueSeparator := ':';
for I := 0 to sl.Count-1 do begin
sl[I] := TrimLeft(sl[I]);
if SameText(sl.Names[I], 'Domain Status') then begin
status := Trim(sl.ValueFromIndex[I]);
status := Copy(status, 1, Pos(' ', status)-1);
Memo1.Lines.Add(status);
end;
end;
finally
sl.Free;
end;
另一种方法是使用正则表达式。有点矫枉过正,但如果您可以保留正则表达式而不是每次使用都重新创建它,性能可以相提并论。
procedure TForm1.Button1Click(Sender: TObject);
Var
RegExDomainStatus : TRegEx;
Match : TMatch;
Alltext : string;
begin
RegExDomainStatus.Create('(?<=^domain status: )[A-z]+',[roIgnoreCase,roMultiline]);
Alltext := Memo1.Lines.Text;
Memo1.Lines.Clear;
match := RegExDomainStatus.Match(AllText);
while match.Success do
begin
memo1.Lines.add(match.Value);
match := match.NextMatch;
end;
end;