Find function

Got a LiveCode personal license? Are you a beginner, hobbyist or educator that's new to LiveCode? This forum is the place to go for help getting started. Welcome!

Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller

Post Reply
Rod Edwardson
Posts: 23
Joined: Sun Mar 03, 2013 1:09 am

Find function

Post by Rod Edwardson » Thu May 30, 2013 6:49 pm

Hello

I'm hoping someone can head me in the right direction here. I have a need to isolate a string of characters in the middle of a word and change that string to red; not if present as a prefix or suffix of the word. As an example, if I use the word "entertainment", I would like the find to ignore the "en" as a prefix but find the other existense later in the word. For further info, the tWords that I will be using has a large number of other strings in it but I just included the "en" as an example.

I have the following code as a base:

Code: Select all

on mouseUp
lock screen
put "en" into tWords
repeat for each item tItem in tWords 
find empty
put false into tExit 
repeat until tExit
find chars tItem in field "field a"
if the foundChunk is empty then 
put true into tExit
else 
set the textcolor of the foundChunk to red                
end if
end repeat
end repeat
Any help on how to accomplish this would be appreciated.

Thanks in advance!

dunbarx
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 10305
Joined: Wed May 06, 2009 2:28 pm

Re: Find function

Post by dunbarx » Thu May 30, 2013 8:01 pm

Hi.

I see what you want to do. Insert this just before the line that sets the color:

if char word 2 of the foundChunk -1 = space then next repeat

This is untested, but I hope you see what I am trying to do. Check the character before the foundChunk, and if it is a space then you know you have found the beginning of a word, and try again. You say in your script that you are finding items. I made this as if you were finding words. if you really are dealing with items, then change the space to comma.

Craig Newman

dunbarx
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 10305
Joined: Wed May 06, 2009 2:28 pm

Re: Find function

Post by dunbarx » Thu May 30, 2013 8:32 pm

Hi again,

Having to fool around, I tried:

on mouseUp
lock screen
put "en" into tWords
repeat for each item tItem in tWords
find empty
put false into tExit
repeat until tExit
find chars tItem in field "field a"
if char word 2 of the foundchunk - 1 of fld "field a" = comma then next repeat --or space, as per the previous post

if the foundChunk is empty then
put true into tExit
else
set the textsize of the foundChunk to random(24)          
end if
end repeat
end repeat
end mouseUp

Craig Newman

Rod Edwardson
Posts: 23
Joined: Sun Mar 03, 2013 1:09 am

Re: Find function

Post by Rod Edwardson » Fri May 31, 2013 6:04 am

Craig

Thank you very much for the assistance. I have it up and running partially thanks to your help. With regard to ignoring the prefix it works great. The find still highlites the same string if it is a suffix of the word. I tried to replicate the same concept for the suffix but run into a loop or something and livecode crashes. I tried the following:

Code: Select all

find chars tItem in field "field a" 
   if char word 2 of the foundChunk -1 of field "Field a" = space  then next repeat --Works great
   if char word 2 of the foundChunk +1 of field "Field a" = space  then next repeat--Crashes
It's probably quite obvious but I'm still learning the livecode world. Thanks again, your help is very much appreciated!

Rod

icouto
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 92
Joined: Wed May 29, 2013 1:54 am

Re: Find function

Post by icouto » Fri May 31, 2013 7:36 am

I've tried the following script in a test stack, and it seems to work fine here - no crashes or endless loops...

Code: Select all

on mouseUp
   lock screen
   local tWords, tExit, tItem
   put "en" into tWords
   repeat for each item tItem in tWords 
      find empty
      put false into tExit 
      repeat until tExit
         find chars tItem in field "test"
         if char ((word 2 of the foundChunk) - 1) of fld "test" = space then next repeat
         if char ((word 2 of the foundChunk) + 1) of fld "test" = space then next repeat
         if the foundChunk is empty then 
            put true into tExit
         else 
            set the foregroundColor of the foundChunk to "red"           
         end if
      end repeat
   end repeat
end mouseUp
Note, however, that space is not the only word delimiter, and depending on what kind of text you are dealing with, you may have to check for additional characters - like return, comma, colon, semi-colon, dashes, single and double quotes, etc.

The following code is another way to go about doing the same job. It is a bit more advanced, as it uses Regular Expressions, or "Regex", to do the finding.The matchChunk function allows us to use Regular Expressions instead of a simple search string:

Code: Select all

on mouseUp
   lock screen
   local tList, tSubstring, tRegex, tOffset, tStartPos, tEndPos
   put "en" into tList
   put 1 into tOffset
   put the number of chars in field "test" into tEndPos
   repeat for each item tSubstring in tList
      -- build Regex we're going to use:
      put "\w+(" & tSubstring & ")\w+" into tRegex
      repeat while matchChunk(char tOffset to tEndPos of field "test", tRegex, tStartPos, tEndPos)
         add (tOffset-1) to tStartPos
         add (tOffset-1) to tEndPos
         set the foregroundColor of char tStartPos to tEndPos of field "test" to "red"
         put tEndPos into tOffset
         put the number of chars in field "test" into tEndPos
      end repeat
   end repeat
end mouseUp
If we take the substring "en" as an example, the regex being used here is "\w+(en)\w+". It looks complicated, but it is actually quite simple. It means: "find one or more characters that are not word-boundaries, followed by 'en', followed again by one or more characters that are not word-boundaries." That is: find "en" in the middle of a word.

The matchChunk function then gives us the position of the "en" in the tStartPos and tEndPos variables, and we use these values to colour the text, and then to offset the next search.

I hope this helps!

dunbarx
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 10305
Joined: Wed May 06, 2009 2:28 pm

Re: Find function

Post by dunbarx » Fri May 31, 2013 2:04 pm

Hi.

You don't mean crashes, just that it does not work, correct?

You may have a sophisticated solution in icouto's regex gadget. But you must pursue your earlier attempt, which in principle was very sound. Think about what the "foundChunk" returns as a value. The second word of the foundChunk is the first char of the found string. So the char before that is the one you want to check.

But for the case of the suffix, is the char just AFTER that char the one of interest? Not quite. Please figure this out. It is not hard. And for a bonus , please find a way to use this method universally, that is, to account for the length of the string you are working with. It will not always be two chars, right?

Write back. You will be tested on this.

Craig Newman

Rod Edwardson
Posts: 23
Joined: Sun Mar 03, 2013 1:09 am

Re: Find function

Post by Rod Edwardson » Fri May 31, 2013 8:30 pm

Thank you both for the information.Tthe regex works great but not with a few other features I need to incorporate. Thanks for the concept for future use though; its much appreciated.

Craig, I get what you are saying and appreciate the teaching environment you have presented. I have figured out the string length with len and placed that in a variable. I will play around abit more tonight when I have time. I'll use that variable in the "if then next repeat " statement by checking if the last char is a space. Love the way you teach a man to fish instead of giving him a salmon steak!

Rod

Rod Edwardson
Posts: 23
Joined: Sun Mar 03, 2013 1:09 am

Re: Find function

Post by Rod Edwardson » Fri May 31, 2013 10:20 pm

I given myself a headache with this one. Still cant get it to work.

Code: Select all

if char (word 2 + (field "stringlength" -2 ) of the foundChunk) of fld "Field a" = " "  then next repeat
if char ((word 2 of the foundChunk) - 1) of fld "Field a" = space then next repeat
If I'm starting with the first char of the foundChunk, I would think what I have here would work. I have accounted for the spaces before and after the string by deducting 2 from the string length. This should give me the last char (which is the space) and move on to the next repeat. The suffix is still highlited red though!

dunbarx
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 10305
Joined: Wed May 06, 2009 2:28 pm

Re: Find function

Post by dunbarx » Sat Jun 01, 2013 12:00 am

Ah.

The human brain. I have one too.

You have to mentally parse this like the engine does. Think like LC. You dismembered the foundChunk reference. Pain is good.

if char (word 2 of the foundChunk + 2) of fld 2 = space then next repeat --for two char string
if char (word 2 of the foundChunk + stringLength) of fld 2 = space then next repeat -- now substitute your string length gadget

What happens if the last foundChunk is the suffix in the last word? Test, test, test.

Craig

Rod Edwardson
Posts: 23
Joined: Sun Mar 03, 2013 1:09 am

Re: Find function

Post by Rod Edwardson » Sat Jun 01, 2013 6:34 am

I believe that is my problem. It is finding the chars in the middle of the string and as a suffix as well. I think what I am seeing is the last find as a suffix. You have me heading in the right direction sensei!

Post Reply