Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

How do I find a string in a ListBox?

1,318 views
Skip to first unread message

Diego Martinez Lopez

unread,
Apr 30, 2003, 2:06:09 PM4/30/03
to
Hi!

I have been searching for a good example for the Delphi Newbie like me.
I only find one article http://bdn.borland.com/article/0,1410,26614,00.html,
but this is not for Delphi???

Please can anyone give me an example how to do this?

Thank you in advance!

Mozilla Ed

unread,
Apr 30, 2003, 2:15:04 PM4/30/03
to

if ListBox1.Items.IndexOf('Ed') <> -1 then
ShowMessage('Found');


--
"Oh bugger! I thought you'd gone." - Ethan

http://www.planeted.co.uk


Diego Martinez Lopez

unread,
Apr 30, 2003, 3:02:34 PM4/30/03
to
> if ListBox1.Items.IndexOf('Ed') <> -1 then
> ShowMessage('Found');
>
Thank you!
That is what I was looking for!

My problem is that I load a html file into the
a listbox so I can get the meta-tags out.
The listbox is has many spaces before the lines.

for example: .....<meta name="Generator">

How can I remove the spaces?
How can I parse the meta value 'Generator'?


Roger Morton

unread,
May 1, 2003, 5:24:07 AM5/1/03
to
In <3eb0...@newsgroups.borland.com>, Diego Martinez Lopez wrote:


>
> My problem is that I load a html file into the
> a listbox so I can get the meta-tags out.
> The listbox is has many spaces before the lines.
>
> for example: .....<meta name="Generator">
>
> How can I remove the spaces?

Use the Trim function

> How can I parse the meta value 'Generator'?
>

- After using Trim, check that the first and last characters are '<'
and '>'

- Use the Pos function to find the '=' character

- Now you know the start (after the '<') and end (before the '=')
positions of the tag name, so use the Copy function to extract it. It
may have leading and trailing spaces (I can't remember whether html
permits them, but it does no harm to assume they might exist).

- Likewise, you know the start and end positions of the tag value.
Again, it may have leading and trailing spaces, and will also be
surrounded by " characters.

--
Roger Morton
ro...@chez-morton.com

Diego Martinez Lopez

unread,
May 1, 2003, 11:39:34 AM5/1/03
to
> Use the Trim function

I am using a trim function from Bob Swart, but it does not work
very well, or I use it wrong?

Const
Space = #$20;

function LTrim(Str: String): String;
var len: Byte absolute Str;
i: Integer;
begin
i := 1;
while (i < len) and (Str[i] = Space) do Inc(i);
LTrim := Copy(Str,i,len-i+1)
end {LTrim};

function RTrim(Str: String): String;
var len: Byte absolute Str;
begin
while (Str[len] = Space) do Dec(len);
RTrim := Str
end {RTrim};

function Trim(Str: String): String;
begin
Trim := LTrim(RTrim(Str))
end {Trim};

and when I test it with

test := ' Hello ';
Trim(test);
Listbox.Items.Add(Test);

It still not removes the spaces?

> > How can I parse the meta value 'Generator'?
> - After using Trim, check that the first and last characters are '<'
> and '>'

How do I check that? Can you show me this please?

> - Use the Pos function to find the '=' character

Which function is better to use? Pos or AnsiPos?


Roger Morton

unread,
May 1, 2003, 12:11:12 PM5/1/03
to
In <3eb13f6d$1...@newsgroups.borland.com>, Diego Martinez Lopez wrote:


>
> I am using a trim function from Bob Swart, but it does not work
> very well, or I use it wrong?
>

Delphi 5, and possibly earlier, has its own Trim functions, in
Sysutils.pas. Look for "string handling routines" in the Help. I
suspect they are functionally equivalent to Bob Swart's.

>
> and when I test it with
>
> test := ' Hello ';
> Trim(test);
> Listbox.Items.Add(Test);
>
> It still not removes the spaces?
>

Yes it does, but you're ignoring the result <g> It's a *function*,
that returns the trimmed value, so you need

test := Trim(test);

> > - After using Trim, check that the first and last characters are
> '<'
> > and '>'
>
> How do I check that? Can you show me this please?
>

if test[1] <> '<' then......

I'll leave you to figure out how to index the last character <g>

You need to decide how to handle an error - do you want to raise an
exception, or warn the user with ShowMessage and return an empty
result, or what?

> > - Use the Pos function to find the '=' character
>
> Which function is better to use? Pos or AnsiPos?
>

AnsiPos is probably safer.

--
Roger Morton
ro...@chez-morton.com

Diego Martinez Lopez

unread,
May 1, 2003, 1:40:36 PM5/1/03
to
> Yes it does, but you're ignoring the result <g> It's a *function*,
> that returns the trimmed value, so you need
>
> test := Trim(test);
>
Ah great! Thank you! This is my fith day of learning Delphi and stupid
mistakes I do not see for myself yet.,

If I want to trim the items(strings) in my stringlist it refuses because
they
are not compatible?

I do it like this:
var HTMLcode : TStringList;
begin
HTMLcode := TStringList.Create;

//This works when I want the strings added to the listbox:
for i := 0 to HTMLcode.Count-1 do
Listbox.Items.Add(HTMLcode[i]);

//I want to trim the strings, but it does not want to work like this.
for i := 0 to HTMLcode.Count-1 do
HTMLcode := Trim(HTMLcode.Strings[i]);

> if test[1] <> '<' then......
Yes, that sounds logic to me too :-)

> You need to decide how to handle an error - do you want to raise an
> exception, or warn the user with ShowMessage and return an empty
> result, or what?

No, it only needs to check if it is there. The concept about this idea is
checking
if there is selfconstructed meta tag <BroswerCmd=......> everytime
TWebBrowser
is finished with loading a new page. If it contains this meta tag I want my
application
execute the meta tag with ShellExecute. for example: <BroswerCmd=C:\Program
Files\
Outlook Express\wab.exe> would launch the adressbook after the page is
loaded.

> AnsiPos is probably safer.
Okay thank you! I will experiment with that now.

Diego


Roger Morton

unread,
May 1, 2003, 2:18:50 PM5/1/03
to
In <3eb15bc9$1...@newsgroups.borland.com>, Diego Martinez Lopez wrote:


>
> If I want to trim the items(strings) in my stringlist it refuses
> because
> they
> are not compatible?
>

> HTMLcode := TStringList.Create;


>
> //I want to trim the strings, but it does not want to work like this.
> for i := 0 to HTMLcode.Count-1 do
> HTMLcode := Trim(HTMLcode.Strings[i]);
>

Should be
HTMLcode[i] := Trim(HTMLcode.Strings[i]);

Or a bit neater:
HTMLcode[i] := Trim(HTMLcode[i]);

Strings is the default property of a TStringList, so HTMLcode[i] is
equivalent to HTMLcode.Strings[i], for both reading and writing.


--
Roger Morton
ro...@chez-morton.com

Diego Martinez Lopez

unread,
May 1, 2003, 3:26:52 PM5/1/03
to
> Should be
> HTMLcode[i] := Trim(HTMLcode.Strings[i]);
>
> Or a bit neater:
> HTMLcode[i] := Trim(HTMLcode[i]);
>
> Strings is the default property of a TStringList, so HTMLcode[i] is
> equivalent to HTMLcode.Strings[i], for both reading and writing.
>
Hi again!

for i := 0 to HTMLcode.Count-1 do

HTMLcode[i] := Trim(HTMLcode.Strings[i]);

and

for i := 0 to HTMLcode.Count-1 do

HTMLcode[i] := Trim(HTMLcode[i]);

results in:

Debugger Exception Notification:
Project Project1.exe raised exception class EStringListError with
message 'List Index out of bounds(4376948). Process stopped.

Diego

Rhys Sage

unread,
May 1, 2003, 4:03:49 PM5/1/03
to
I haven't checked the entire thread but... if htmlcode is a TStringList or a
TListBox then in the first example, you're indexing in the wrong place.
HTMLCode is a list. Strings is a property of an item in the list. Hence
HTMLCode[i].Strings will work.

In the second example, the problem is you're telling it to trim a list item
but not what part of the list item to trim.

--
Yours,

Rhys Sage.

Thought of the day:
"Work saves us from three great evils -
vice, boredom and need"

-Voltaire

(Team Zip)

"Diego Martinez Lopez" <diego_marti...@hotmail.com> wrote in
message news:3eb1...@newsgroups.borland.com...

Roger Morton

unread,
May 2, 2003, 5:06:33 AM5/2/03
to
In <3eb1...@newsgroups.borland.com>, Diego Martinez Lopez wrote:


>
> for i := 0 to HTMLcode.Count-1 do
> HTMLcode[i] := Trim(HTMLcode[i]);
>
> results in:
>
> Debugger Exception Notification:
> Project Project1.exe raised exception class EStringListError with
> message 'List Index out of bounds(4376948). Process stopped.
>

Diego

That's a very odd error; the only way in which I can see the 'for'
loop failing would be if 'i' was declared as a unsigned type and if the
list was empty - but then the bounds failure would be at 0, not
4376948. The latter implies that some kind of random indexing into the
list is taking place - I doubt that you've really got more than 4
million items in it <g>.

Are you sure the debugger is halting inside the for loop, and not
somewhere else in your code?


--
Roger Morton
ro...@chez-morton.com

Diego Martinez Lopez

unread,
May 2, 2003, 8:06:28 AM5/2/03
to
> That's a very odd error; the only way in which I can see the 'for'
> loop failing would be if 'i' was declared as a unsigned type and if the
> list was empty - but then the bounds failure would be at 0, not
> 4376948. The latter implies that some kind of random indexing into the
> list is taking place - I doubt that you've really got more than 4
> million items in it <g>.

Hi Roger!
I am sorry I am possible boring you much with my question's.

No not 4 million, only 20 strings, but I think it is my fault.
I forgot to use a StringList.Free at the end. Delphi was not
responding as it should, because suddenly all the Delphi Examples
(which worked before) did not compile any more. After a reboot
the problem was solved. :-)

It works like this now:

For i := 0 To HTMLcode.Count-1 Do
Begin
HTMLcode.Strings[i] := Trim(HTMLcode.Strings[i]);
HTMLcode.Strings[i] := StringReplace(HTMLcode.Strings[i], '<', '',
[rfReplaceAll]);
HTMLcode.Strings[i] := StringReplace(HTMLcode.Strings[i], '>', '',
[rfReplaceAll]);
HTMLcode.Strings[i] := StringReplace(HTMLcode.Strings[i], '/', '',
[rfReplaceAll]);
Listbox.Items.Add(HTMLcode.Strings[i]);
HTMLcode.Free;
End

So all strings are trimmed, and all unwanted characters are removed from the
stringlist
Now I want to get this part: ' meta cmd="ShellExecute(Notepad)" ' from the
stringlist which
looks like this:
..
meta name="Description" content="Just a test"
meta cmd="ShellExecute(Notepad)"
meta name="Keywords" content="WebBrowser"
...

I tried to find the string by using:

if ListBox.Items.IndexOf('meta cmd=') <> -1 then
ShowMessage('Found');

This does not work because I do not have the full string.
Which is of course impossible, because I cannot guess what
is going to be behind the meta cmd=. :-)

How can I search on a piece of string? Select the entire string
and copy to another string so I can parse this one?
I tried to Parse the strings in the stringlist like this:

(borrowed parse function)
function Parse(Char, S: string; Count: Integer): string;
var
I: Integer;
T: string;
begin
if S[Length(S)] <> Char then
S := S + Char;
for I := 1 to Count do
begin
T := Copy(S, 0, Pos(Char, S) - 1);
S := Copy(S, Pos(Char, S) + 1, Length(S));
end;
Result := T;
end;

So I tried:

For i := 0 To HTMLcode.Count-1 Do
Begin
HTMLcode.Strings[i] := Parse(''meta cmd=', HTMLcode.Strings[i], 2);
End

And this ends up in an Acces Violation. (Because I proberbly use it wrong)
:-(

Can you give me pointer how to do this right? Should I use another function
or
approach?

Regards,

Diego

Roger Morton

unread,
May 2, 2003, 9:32:06 AM5/2/03
to
In <3eb2...@newsgroups.borland.com>, Diego Martinez Lopez wrote:


>
> So all strings are trimmed, and all unwanted characters are removed
> from the
> stringlist

Great. That's the kind of code I think you might end up rewriting from
time to time <g>

>
> How can I search on a piece of string? Select the entire string
> and copy to another string so I can parse this one?
> I tried to Parse the strings in the stringlist like this:
>
> (borrowed parse function)
> function Parse(Char, S: string; Count: Integer): string;
> var
> I: Integer;
> T: string;
> begin
> if S[Length(S)] <> Char then
> S := S + Char;
> for I := 1 to Count do
> begin
> T := Copy(S, 0, Pos(Char, S) - 1);
> S := Copy(S, Pos(Char, S) + 1, Length(S));
> end;
> Result := T;
> end;
>

That looks a bit weird; it seems to be designed for testing multiple
instances of single characters, but you're trying to feed it a string
(called 'Char') to search for.

>
> Can you give me pointer how to do this right? Should I use another
> function
> or
> approach?
>

What's wrong with what I suggested before - search for the '=' sign in
each entry in the list, and split it into name and value elements?

procedure MySplit(Base: string; SplitChar: Char; var Before, After:
String);
var
I: Integer;
begin
I := AnsiPos(SplitChar, Base);
if I = 0 then I := Length(Base) + 1; // Pretend split comes beyond
the end
Before := Copy(Base, 1, I - 1);
After := Copy(Base, I + 1, Length(Base));
end;

var
TagName, TagValue: string;
N: Integer;
.....

for N := 0 to HTMLcode.Count - 1 do
begin
MySplit(HTMLcode[i], '=', TagName, TagValue);
if TagName = 'meta cmd' then
...... do something clever with TagValue
end;


--
Roger Morton
ro...@chez-morton.com

Diego Martinez Lopez

unread,
May 2, 2003, 10:00:29 AM5/2/03
to
Great! This works indeed perfect!
Thank you for your patience and the
many examples. I start understanding
now how it works :-)

Thank you!!!

Diego

"Roger Morton" <ro...@xnospamxchez-morton.com> wrote in message
news:cpaOQ3ygEde46wDA8DgiHw@LOFT...

0 new messages