Grabbing Data Between Two Key Words... (Real Studio network user group Mailinglist archive)

Back to the thread list
Previous thread: Generating Images?
Next thread: Delay on first playsound


[OT] more Carbon shared library tales   -   Hadley, Joshua
  Grabbing Data Between Two Key Words...   -   Maury McCown
   Re: Grabbing Data Between Two Key Words...   -   Frank Bitterlich
    Re: Grabbing Data Between Two Key Words...   -   Maury McCown
     Re: Grabbing Data Between Two Key Words...   -   George Clark
      Re: Grabbing Data Between Two Key Words...   -   Maury McCown
      Re: Grabbing Data Between Two Key Words...   -   Maury McCown
       Re: Grabbing Data Between Two Key Words...   -   George Clark
        Re: Grabbing Data Between Two Key Words...   -   Maury McCown
     Re: Grabbing Data Between Two Key Words...   -   Owen Yamauchi
     Re: Grabbing Data Between Two Key Words...   -   Frank Bitterlich
    Re: Grabbing Data Between Two Key Words...   -   William Squires
   Re: Grabbing Data Between Two Key Words...   -   Thomas Reed
    Re: Grabbing Data Between Two Key Words...   -   Maury McCown
   Re: Grabbing Data Between Two Key Words...   -   Paul Goracke
    Re: Grabbing Data Between Two Key Words...   -   Paul Goracke

Grabbing Data Between Two Key Words...
Date: 13.12.02 23:15 (Fri, 13 Dec 2002 16:15:01 -0600)
From: Maury McCown
Hey all

I have a feeling that this is going to be an embarrassingly easy "problem"
to solve, but my brain's working on about 3 hours of sleep and two days of
potent allergy medication. Disclaimers aside, here's what I'm looking to do
(illustrated with a theoretical animal program):

Let's say I have a text file. The first line is something like "Cat" and
then there's an unknown number of cat species listed, each followed by a
return.

Next in the text file, after the cat species, is the word "Dog" and then an
unknown number of dog species listed.

Next there's the word "Bird" and then a list of birds, and so on and so
forth.

What I want to do is be able to have my app recognize the "Cats" keyword,
recognize the "Dog" keyword, and read all the data in between into another
list box. Likewise, I want the app to recognize the "Bird" keyword and read
the data between "Dog" and "Bird" into another list box, etc., etc., etc.

Every line is followed by a hard return, too, FWIW.

Any ideas on the best way to handle this?
TIA,
Maury

---
A searchable archive of this list is available at:
<http://dbserver.realsoftware.com/KBDB/search.php>

Unsubscribe:
<mailto:<email address removed>>

Subscribe to the digest:
<mailto:<email address removed>>

Re: Grabbing Data Between Two Key Words...
Date: 13.12.02 23:30 (Fri, 13 Dec 2002 23:30:15 +0100)
From: Frank Bitterlich
Just loop over the lines of the file until you hit an EOF; in the loop,
do something like this...

const keywords="$cats$dogs$birds$weasels$"
dim oneLine, currentCategory as string

currentCategory = "unspecified"
do until strm.eof
oneLine = strm.ReadLine
if InStr(keywords, "$"+oneLine+"$") > 0 then
currentCategory = oneLine
else
DoSomethingWith(oneLine, currentCategory)
end if
loop

HTH,
Frank+++

Maury McCown wrote:
>
> Hey all
>
> I have a feeling that this is going to be an embarrassingly easy "problem"
> to solve, but my brain's working on about 3 hours of sleep and two days of
> potent allergy medication. Disclaimers aside, here's what I'm looking to do
> (illustrated with a theoretical animal program):
>
> Let's say I have a text file. The first line is something like "Cat" and
> then there's an unknown number of cat species listed, each followed by a
> return.
>
> Next in the text file, after the cat species, is the word "Dog" and then an
> unknown number of dog species listed.
>
> Next there's the word "Bird" and then a list of birds, and so on and so
> forth.
>
> What I want to do is be able to have my app recognize the "Cats" keyword,
> recognize the "Dog" keyword, and read all the data in between into another
> list box. Likewise, I want the app to recognize the "Bird" keyword and read
> the data between "Dog" and "Bird" into another list box, etc., etc., etc.
>
> Every line is followed by a hard return, too, FWIW.
>
> Any ideas on the best way to handle this?
> TIA,
> Maury

Re: Grabbing Data Between Two Key Words...
Date: 14.12.02 02:35 (Fri, 13 Dec 2002 19:35:56 -0600)
From: Maury McCown
On 12/13/02 4:30 PM, Frank Bitterlich uttered the following:

> Just loop over the lines of the file until you hit an EOF; in the loop,
> do something like this...
>
> const keywords="$cats$dogs$birds$weasels$"
> dim oneLine, currentCategory as string
>
> currentCategory = "unspecified"
> do until strm.eof
> oneLine = strm.ReadLine
> if InStr(keywords, "$"+oneLine+"$") > 0 then
> currentCategory = oneLine
> else
> DoSomethingWith(oneLine, currentCategory)
> end if
> loop

This works, but all I can get it to return is the discovered keywords -- not
the data in between those keywords. Here's an example of what this file
could look like (and I labeled the keywords):

Dogs <- Keyword
Poodle
Terrier
Mutt
Cats <- Keyword
Siamese
Tabby

This is an already-existing file (and I know all the keywords), so I'm
limiting myself the the file's layout. What I really want is to have my app
go...

Here's keyword 1 and here's keyword 2, so grab all the lines of data between
the two and add them to listbox1. Here's keyword 3, so grab all the lines
between keyword 2 and keyword 3 and dump them into listbox2, and so on and
so forth.

That said, the keywords are simply placeholders or headings -- what want is
the data in between.

Does that make more sense?
Maury

---
A searchable archive of this list is available at:
<http://dbserver.realsoftware.com/KBDB/search.php>

Unsubscribe:
<mailto:<email address removed>>

Subscribe to the digest:
<mailto:<email address removed>>

Re: Grabbing Data Between Two Key Words...
Date: 14.12.02 06:08 (Sat, 14 Dec 2002 00:08:06 -0500)
From: George Clark
On 12/13/02 20:35, Maury McCown wrote:

> On 12/13/02 4:30 PM, Frank Bitterlich uttered the following:
>
>> Just loop over the lines of the file until you hit an EOF; in the loop,
>> do something like this...
>>
>> const keywords="$cats$dogs$birds$weasels$"
>> dim oneLine, currentCategory as string
>>
>> currentCategory = "unspecified"
>> do until strm.eof
>> oneLine = strm.ReadLine
>> if InStr(keywords, "$"+oneLine+"$") > 0 then
>> currentCategory = oneLine
>> else
>> DoSomethingWith(oneLine, currentCategory)
>> end if
>> loop
>
> This works, but all I can get it to return is the discovered keywords -- not
> the data in between those keywords. Here's an example of what this file
> could look like (and I labeled the keywords):
>
> Dogs <- Keyword
> Poodle
> Terrier
> Mutt
> Cats <- Keyword
> Siamese
> Tabby
>
> This is an already-existing file (and I know all the keywords), so I'm
> limiting myself the the file's layout. What I really want is to have my app
> go...
>
> Here's keyword 1 and here's keyword 2, so grab all the lines of data between
> the two and add them to listbox1. Here's keyword 3, so grab all the lines
> between keyword 2 and keyword 3 and dump them into listbox2, and so on and
> so forth.
>
> That said, the keywords are simply placeholders or headings -- what want is
> the data in between.

What Frank posted will do what you want; you just need to process the data
(i.e., non-keyword) lines in the Else clause. Here's a slight variation:

const keywords="$cats$dogs$birds$weasels$"
dim oneLine as string
Dim lb As ListBox
'If you have a special subclass of ListBox,
' dim lb as that subclass instead

do until strm.eof
oneLine = strm.ReadLine

'in case the file ends with a <return>
' or has blank lines...
If oneline <> "" Then
if InStr(keywords, "$"+oneLine+"$") > 0 then

Select Case oneline
Case "Cats"
lb = CatsListBox
Case "Dogs"
lb = DogsListBox
Case "Birds"
lb = BirdsListBox
End Select
' use the names of your listboxes, of course
else
lb.addrow oneline
end if
End if
loop

strm.close

You could read in the entire file and use NthField in a similar fashion.

You *could* do it the way you say you want to do it by reading in the entire
file, then using NthField to first go through and 'find' where the keywords
are, using variables (an array or dictionary comes to mind) to hold those
positions, then use your stored values to extract the relevant lines for
each listbox. But that's extra processing that's not strictly speaking
necessary. If you really want to do it that way, I have a 'List' class that
basically uses NthField 'behind the scenes' that may be useful. Let me know
off-list if you'd like to try it.

George

Re: Grabbing Data Between Two Key Words...
Date: 14.12.02 14:59 (Sat, 14 Dec 2002 07:59:12 -0600)
From: Maury McCown
On 12/13/02 11:08 PM, George Clark uttered the following:

> What Frank posted will do what you want; you just need to process the data
> (i.e., non-keyword) lines in the Else clause. Here's a slight variation:

<SNIP>

This works great after making the necessary modifications -- thanks for the
help!

Maury
===========================================
RAILhead Design: ³Giving the planet a makeover²
news | icons | desktops | fonts | software | more
< http://www.railheaddesign.com/ >
===========================================


---
A searchable archive of this list is available at:
<http://dbserver.realsoftware.com/KBDB/search.php>

Unsubscribe:
<mailto:<email address removed>>

Subscribe to the digest:
<mailto:<email address removed>>

Re: Grabbing Data Between Two Key Words...
Date: 15.12.02 04:01 (Sat, 14 Dec 2002 21:01:19 -0600)
From: Maury McCown
On 12/13/02 11:08 PM, George Clark uttered the following:

> What Frank posted will do what you want; you just need to process the data
> (i.e., non-keyword) lines in the Else clause. Here's a slight variation:
>
> const keywords="$cats$dogs$birds$weasels$"
> dim oneLine as string
> Dim lb As ListBox
> 'If you have a special subclass of ListBox,
> ' dim lb as that subclass instead
>
> do until strm.eof
> oneLine = strm.ReadLine
>
> 'in case the file ends with a <return>
> ' or has blank lines...
> If oneline <> "" Then
> if InStr(keywords, "$"+oneLine+"$") > 0 then
>
> Select Case oneline
> Case "Cats"
> lb = CatsListBox
> Case "Dogs"
> lb = DogsListBox
> Case "Birds"
> lb = BirdsListBox
> End Select
> ' use the names of your listboxes, of course
> else
> lb.addrow oneline
> end if
> End if
> loop
>
> strm.close

This code worked great -- but here's another possible twist: this only works
if there's no text before the first keyword in the constant list. Is there
something I can do to have it read and ignore anything that appears BEFORE
the first keyword?

Maury
===========================================
RAILhead Design: ³Giving the planet a makeover²
news | icons | desktops | fonts | software | more
< http://www.railheaddesign.com/ >
===========================================


---
A searchable archive of this list is available at:
<http://dbserver.realsoftware.com/KBDB/search.php>

Unsubscribe:
<mailto:<email address removed>>

Subscribe to the digest:
<mailto:<email address removed>>

Re: Grabbing Data Between Two Key Words...
Date: 15.12.02 05:14 (Sat, 14 Dec 2002 23:14:19 -0500)
From: George Clark
Change the Else clause to:

Elseif lb <> nil Then...

Until a valid keyword has been found 'lb' won't have a value.

George

On 12/14/02 22:01, Maury McCown wrote:

> On 12/13/02 11:08 PM, George Clark uttered the following:
>
>> What Frank posted will do what you want; you just need to process the data
>> (i.e., non-keyword) lines in the Else clause. Here's a slight variation:
>>
>> const keywords="$cats$dogs$birds$weasels$"
>> dim oneLine as string
>> Dim lb As ListBox
>> 'If you have a special subclass of ListBox,
>> ' dim lb as that subclass instead
>>
>> do until strm.eof
>> oneLine = strm.ReadLine
>>
>> 'in case the file ends with a <return>
>> ' or has blank lines...
>> If oneline <> "" Then
>> if InStr(keywords, "$"+oneLine+"$") > 0 then
>>
>> Select Case oneline
>> Case "Cats"
>> lb = CatsListBox
>> Case "Dogs"
>> lb = DogsListBox
>> Case "Birds"
>> lb = BirdsListBox
>> End Select
>> ' use the names of your listboxes, of course
>> else
>> lb.addrow oneline
>> end if
>> End if
>> loop
>>
>> strm.close
>
> This code worked great -- but here's another possible twist: this only works
> if there's no text before the first keyword in the constant list. Is there
> something I can do to have it read and ignore anything that appears BEFORE
> the first keyword?
>
> Maury
> ===========================================
> RAILhead Design: ³Giving the planet a makeover²
> news | icons | desktops | fonts | software | more
> < http://www.railheaddesign.com/ >
> ===========================================
>
>
>
> ---
> A searchable archive of this list is available at:
> <http://dbserver.realsoftware.com/KBDB/search.php>
>
> Unsubscribe:
> <mailto:<email address removed>>
>
> Subscribe to the digest:
> <mailto:<email address removed>>


George

--

Re: Grabbing Data Between Two Key Words...
Date: 15.12.02 05:55 (Sat, 14 Dec 2002 22:55:59 -0600)
From: Maury McCown
On 12/14/02 10:14 PM, George Clark uttered the following:

> Change the Else clause to:
>
> Elseif lb <> nil Then...
>
> Until a valid keyword has been found 'lb' won't have a value.

D'oh! Thanks. =)

Maury

---
A searchable archive of this list is available at:
<http://dbserver.realsoftware.com/KBDB/search.php>

Unsubscribe:
<mailto:<email address removed>>

Subscribe to the digest:
<mailto:<email address removed>>

Re: Grabbing Data Between Two Key Words...
Date: 14.12.02 13:36 (Sat, 14 Dec 2002 13:36:56 +0100)
From: Owen Yamauchi
Maury,

I don't see why you can't do this:

In a window, have ListCats, ListDogs, and ListBirds (all ListBoxes)

dim i as integer
dim s,currentline,currentset as string

s=(all data read from the text file)
for ito CountFields(s,chr(13))
currentline=nthField(s,chr(13),i)
if currentline="Cats" or currentline="dogs" or currentline="birds" then
currentsetÀrrentline
else
if currentset="Cats" then
ListCats.AddRow currentline
elseif currentset="Dogs" then
ListDogs.AddRow currentline
elseif currentset="Birds" then
ListBirds.AddRow currentline
end if
end if
next

Regards,

-

Re: Grabbing Data Between Two Key Words...
Date: 16.12.02 14:22 (Mon, 16 Dec 2002 14:22:11 +0100)
From: Frank Bitterlich
Hi Maury,

the code I posted should work just fine; you just need to create your
own subroutine called "DoSomethingWith" that takes two arguments: The
first one is the name of the actual pet (poodle, siamese, whatever), and
the second one is the name of the "category" or "keyword" (dogs, cats,
...). It even works for entries that stand BEFORE the first keyword
(they get the category "unspecified"), and it is completely
case-insensitive (contrary to what William Squires wrote <g>). It's only
weakness is when it comes to a) blank lines and b)
unrecognized/unexpected keywords. And with this file format there's no
possible solution to b).

Try it; if you use my code without modification, just add the following
procedure, it will work. Trust me ;)

Sub DoSomethingWith(specificPet as string, category as string)
ListBox1.AddRow SpecificPet
ListBox1.Cell(ListBox1.LastIndex, 1) = category
End Sub

(Of yourse you must modify this procedure so that it fills multiple
listboxes insted of one).

Cheers,
Frank+++

Maury McCown wrote:
>
> On 12/13/02 4:30 PM, Frank Bitterlich uttered the following:
>
> > Just loop over the lines of the file until you hit an EOF; in the loop,
> > do something like this...
> >
> > const keywords="$cats$dogs$birds$weasels$"
> > dim oneLine, currentCategory as string
> >
> > currentCategory = "unspecified"
> > do until strm.eof
> > oneLine = strm.ReadLine
> > if InStr(keywords, "$"+oneLine+"$") > 0 then
> > currentCategory = oneLine
> > else
> > DoSomethingWith(oneLine, currentCategory)
> > end if
> > loop
>
> This works, but all I can get it to return is the discovered keywords -- not
> the data in between those keywords. Here's an example of what this file
> could look like (and I labeled the keywords):
>
> Dogs <- Keyword
> Poodle
> Terrier
> Mutt
> Cats <- Keyword
> Siamese
> Tabby
>
> This is an already-existing file (and I know all the keywords), so I'm
> limiting myself the the file's layout. What I really want is to have my app
> go...
>
> Here's keyword 1 and here's keyword 2, so grab all the lines of data between
> the two and add them to listbox1. Here's keyword 3, so grab all the lines
> between keyword 2 and keyword 3 and dump them into listbox2, and so on and
> so forth.
>
> That said, the keywords are simply placeholders or headings -- what want is
> the data in between.
>
> Does that make more sense?
> Maury

Re: Grabbing Data Between Two Key Words...
Date: 14.12.02 15:37 (Sat, 14 Dec 2002 08:37:19 -0600)
From: William Squires
Hi!

On Friday, December 13, 2002, at 04:30 PM, Frank Bitterlich wrote:

> Just loop over the lines of the file until you hit an EOF; in the loop,
> do something like this...
>
> const keywords="$cats$dogs$birds$weasels$"
> dim oneLine, currentCategory as string
>
> currentCategory = "unspecified"
> do until strm.eof
> oneLine = strm.ReadLine

Change:
> if InStr(keywords, "$"+oneLine+"$") > 0 then

to:
if InStr(LCase(keywords), "$" + oneLine + "$") > 0 then

so that varying case in the input line doesn't trip you up.

> currentCategory = oneLine
> else
> DoSomethingWith(oneLine, currentCategory)
> end if
> loop
>
> HTH,
> Frank+++
>
> Maury McCown wrote:
>>
etc...

If you can get away with requiring a ":" after each keyword, and each
keyword on it's own line, you can take a shortcut, and just look for
the ":" with instr, like:

<This const will have to go in a module...>
const keywords="$cats$dogs$birds$weasels"

Dim oneLine, currentCategory As String
Dim i As Integer
Dim keyWord As String

// Code to open TextInputStream here...
// yada, yada.

// Look for keywords
currentCategory = "unspecified"
Do Until (strm.eof)
oneLine = strm.ReadLine
i = InStr(oneLine, ":")
// if InStr(keywords, "$"+oneLine+"$") > 0 then
if (i > 0) Then
// Possible keyword
keyWord = "$" + Left(oneLine, i-1)
If InStr(keywords, keyWord) > 0 Then
currentCategory = oneLine
Else
DoSomethingWith(oneLine, currentCategory)
End If
Else
// Not a keyword
DoSomethingWith(oneLine, currentCategory)
End If
Loop

Now you'll have a keyword line like:

cat:<0-N whitespace chars><Newline char(s)>

or even:

cat:<0-N whitespace chars>// This defines the cats used in the
program!<Newline char(s)>

Enjoy! :)

---
A searchable archive of this list is available at:
<http://dbserver.realsoftware.com/KBDB/search.php>

Unsubscribe:
<mailto:<email address removed>>

Subscribe to the digest:
<mailto:<email address removed>>

Re: Grabbing Data Between Two Key Words...
Date: 13.12.02 23:45 (Fri, 13 Dec 2002 16:45:58 -0600)
From: Thomas Reed
>What I want to do is be able to have my app recognize the "Cats" keyword,
>recognize the "Dog" keyword, and read all the data in between into another
>list box. [...]
>
>Every line is followed by a hard return, too, FWIW.

Sounds like you're taking the wrong approach. You shouldn't make
"Cats", "Dogs" and "Birds" keywords. What happens if the file has a
"Reptiles" list?

I'm going to assume your file looks something like this:

Dogs
poodle,terrier,mutt,...
Cats
...

If this is incorrect, just adjust the advice according to what the
file actually looks like.

So, I would read all this into a string (let's call it s). You can
break this up into the individual lists like this:

dim n, i as integer
dim cr, animalType, animalList as string

cr = chr(13) // for a Mac-style hard return
n = CountFields(s, cr)
i = 1
while i < n
animalType = NthField(s, cr, i)
animalList = NthField(s, cr, i+1)
i = i + 2
AddToListBox(animalType, animalList)
wend

So, in the first time through the loop, animalType would contain
"Dogs" and animalList would contain "poodle,terrier,mutt,...". You'd
do whatever is needed to put this in the list, parsing each animal
list further using CountFields and NthField with comma as the field
separator instead of carriage return.

Hope this helps!

Re: Grabbing Data Between Two Key Words...
Date: 14.12.02 01:18 (Fri, 13 Dec 2002 18:18:29 -0600)
From: Maury McCown
On 12/13/02 4:45 PM, Thomas Reed uttered the following:

>> What I want to do is be able to have my app recognize the "Cats" keyword,
>> recognize the "Dog" keyword, and read all the data in between into another
>> list box. [...]
>>
>> Every line is followed by a hard return, too, FWIW.
>
> Sounds like you're taking the wrong approach. You shouldn't make
> "Cats", "Dogs" and "Birds" keywords. What happens if the file has a
> "Reptiles" list?
>
> I'm going to assume your file looks something like this:
>
> Dogs
> poodle,terrier,mutt,...
> Cats

Actually, the list would be something like;

Dogs
Poodle
Terrier
Mutt
Cats
Siamese
Tabby

Etc.

As for the format, I'll be manipulating an already-existing file that will
be retrieved from a server, thus, I'm forced to work with the file as it is.

Maury

---
A searchable archive of this list is available at:
<http://dbserver.realsoftware.com/KBDB/search.php>

Unsubscribe:
<mailto:<email address removed>>

Subscribe to the digest:
<mailto:<email address removed>>

Re: Grabbing Data Between Two Key Words...
Date: 14.12.02 00:31 (Fri, 13 Dec 2002 15:31:42 -0800)
From: Paul Goracke
Maury McCown wrote:

> What I want to do is be able to have my app recognize the "Cats"
> keyword,
> recognize the "Dog" keyword, and read all the data in between into
> another
> list box. Likewise, I want the app to recognize the "Bird" keyword and
> read
> the data between "Dog" and "Bird" into another list box, etc., etc.,
> etc.

1. Create a Dictionary that maps the keyword to the list in which to
add the following lines. I'd probably make it a property of the window
containing all the lists, but your app may differ. Assuming the lists
are named "ListDog," "ListCat," "ListBird," etc.:

keyList = New Dictionary
keyList.Value( "Dog" ) = ListDog
keyList.Value( "Cat" ) = ListCat
keyList.Value( "Bird" ) = ListBird

2. Import and sort into bins (aka "your lists") as you go:

Dim i As Integer
Dim line As String
Dim currentList As Listbox
Dim v As Variant

Do
line = stream.ReadLine
If keyList.HasKey( line ) Then
// it's a key, set the currentList
currentList = Listbox( keyList.Value( line ).ObjectValue )
Elseif currentList <> Nil Then
// if there's no currentList, we haven't encountered a key yet
currentList.AddRow line
End If
Loop Until stream.EOF

3. That's it; you're done.

pg

---
A searchable archive of this list is available at:
<http://dbserver.realsoftware.com/KBDB/search.php>

Unsubscribe:
<mailto:<email address removed>>

Subscribe to the digest:
<mailto:<email address removed>>

Re: Grabbing Data Between Two Key Words...
Date: 14.12.02 00:36 (Fri, 13 Dec 2002 15:36:08 -0800)
From: Paul Goracke
I wrote:

> Dim i As Integer
> Dim line As String
> Dim currentList As Listbox
> Dim v As Variant

Ignore both the i and v declarations--they're no longer used in the code
I presented.

pg

---
A searchable archive of this list is available at:
<http://dbserver.realsoftware.com/KBDB/search.php>

Unsubscribe:
<mailto:<email address removed>>

Subscribe to the digest:
<mailto:<email address removed>>