Reputation: 1513
I use the following function to search a TStringList I am reading from a file. I know that when I search a value, then the return value I need is always on the line after the one with the item I search. It has always worked using POS to search, but now the file has been expanded and I have to look for 2 items 'Adresse' and 'Adresse 2' That gives me an issue since pos finds 'Adresse' in both cases and my data is then wrong.
Is there another method of searching a string for a substring that I don't know of or do I have to make my own.
function FindValue(const aFilename, aSearch: string): string;
var
InfoList: TStringList;
Counter: integer;
begin
InfoList := TStringList.Create;
try
InfoList.LoadFromFile(aFilename);
if InfoList.Count > 0 then
for Counter := 0 to InfoList.Count - 1 do
begin
if Pos(aSearch, Infolist.Strings[Counter]) > 0 then
Result := Infolist.Strings[Counter + 1]
end
else
Result := '';
finally
InfoList.Free;
end;
end;
For info: the input to the TStringList comes from a textfile extracted from a HTML file. A sample of a file could be:
OZ8HP
Hugo Pedersen
Radioamatør
Nykøbing M
Sendeposition:
Adresse:
Prinsensvej 18
Postnummer:
7900
Bynavn:
Nykøbing M
Antenne højde (m):
Kote (m):?Kote (m):Brugerens/tilladelsesindehaverens øvrige adresseoplysninger så som Stednavn og/eller Postboks. Hjælpetegnet * kan anvendes, som beskrevet i hjælp.
Koordinater:
Geografisk anvendelse:
Frekvensmaske:
Tekniske specifikationer:
Sendeeffekt basisstation:
Sendeeffekt mobile anlæg:
Båndbredde (MHz):
Antal anlæg:
MMSI:
Kaldesignaltype:
Personlig
Frekvenskategori:
Udstedelses-metode:
Intention om overdragelse:
Nej
Udløbsdato:
Brugerdata:
Brugernummer:
956078
Adresse:
Prinsensvej 18
Adresse 2:
Sejerslev
Postnr.:
7900
Bynavn:
Nykøbing M
Kaldesignal-kategori:
Bestået A
Upvotes: 0
Views: 1166
Reputation: 612794
It looks to me as though the real mistake is being too lax in your search. Why accept partial matches? It would seem more robust to look for complete matches
if SameText(aSearch, Infolist[Counter]) then
or perhaps to account for leading and trailing whitespace:
if SameText(aSearch, Trim(Infolist[Counter])) then
You'd need to pass 'Adresse:'
or 'Adresse 2:'
as the search string, or add the colon in the search function.
Use AnsiSameText
if you want locale sensitive comparison. Use =
if you want case sensitive comparison, etc.
You might pass multiple search strings and be able to loop only once over the file. As it stands you read it twice which seems wasteful. Indeed surely better to operate on a string list and not be coupled to file storage.
You return the last match in the data rather than the first, for instance. What if there are multiple matches? Does your code behave as intended?
You should also be aware that if no match is found your function does not assign to the Result
variable which means it is undefined.
Upvotes: 4