Jump to content

This site uses cookies. By continuing to browse the site you are agreeing to our use of cookies. Find out more here. X
X


Photo

String Find and replace


  • Please log in to reply
23 replies to this topic

#1 aommaster

aommaster

    Adventurer

  • Active Members
  • PipPip
  • 140 posts

Posted 29 July 2007 - 07:39 PM

Hi everyone!

I have very little knowledge about programming overall (I have done a C programming course, but, it doesn't seem to help much with autoit!).I'm currently working on an autoit script to play a simpel game of hangman (please, don't ask why :)). So far, this is what I've managed to do.

1.Guess certain letters
2.Input the text into a string. The text inputted has the following format:
_ _ _ _ _ L _ _ _ W _ _ _ _ _ _ _ _ _ _ S _ _ _

So, each letter that has not been guessed us represented by a "_", a space between words is signified by a " ". Now, so far, I have managed to use the function to break the string down into:
***** L *** W *** ***** ** S * **

This was done by replacing "_ " with a "*"
As you can see, this causes a probelm because if there is a letter in the place, you end up with a space between that letter and the next *.

I want to use the find and replace function again, but this time, with a wild card, so that if the script finds "[letter] *", it replaces it wilth "[that same letter]*"

Perhaps if I could say that if it finds " *" and then looks before the " " and sees that it is a letter it does the replacement, but otherwise, i'm not really sure how to do it.

I don't even mind changing the initial replacement.

Please help

Thanks guys!







#2 cramaboule

cramaboule

    Universalist

  • Active Members
  • PipPipPipPipPip
  • 286 posts

Posted 29 July 2007 - 07:55 PM

Do you have a bit of code or better explanation, cause I am not sure what you want... and it should not be difficult !!!

#3 aommaster

aommaster

    Adventurer

  • Active Members
  • PipPip
  • 140 posts

Posted 29 July 2007 - 08:05 PM

Do you have a bit of code or better explanation, cause I am not sure what you want... and it should not be difficult !!!


Thank you for the prompt reply.

The code below is one which is made to get the data from the clipboard (which autoit does in the script)

CODE
$hint = ClipGet()
MsgBox(0, "String obtained is:", $hint) ;To be removed later on!!!
$hint1=(StringReplace($hint, "_ ", "*"))

MsgBox(0, "String is now:", $hint1)

This is the part of the code that I had written to do the replacement. However, as you can see, the replacement is not perfect.

Let me see if I can explain it in a better way.

This is an example input that autoit will get from the clipboard:
_ _ _ _ _ H _ _ _ B _ _ _ _ _ _ _ _ Example 1

This solution to this puzzle has 4 words. In the solution, each letter is denoted by a "_". Each space in the solution is denoted by a " " (three spaces). What I want autoit to do is to manipulation this string above, and convert it into something like this:
***** H*** B*** ***** Example 2

So, all those underscores and extra spaces have been removed. All the underscores have been changed to *'s, and those extra spaces in between words have been brought down to only a single space.

However, the code that i have given you above makes the string look like this:
***** H *** B *** ***** Example 3

There are spaces in between the letters and the *'s that follow them.

As I see it, there are two ways of sorting out the problem:
1.From example 3, write out ANOTHER find and replace to get rid of those extra, unneeded spaces
2.Write a completely different find and replace so that Example 1 is changed to example 2.

hope that helps!

#4 cramaboule

cramaboule

    Universalist

  • Active Members
  • PipPipPipPipPip
  • 286 posts

Posted 29 July 2007 - 09:57 PM

Huh :)


kinda easy but looks like that StringReplace() bugs so far I have this :


Plain Text         
$hint ="_ _ _ _ _ H _ _ _ B _ _ _ _ _ _ _ _ " ;*****H ***B ******** 1. ;***** H*** B******** 2. ;$hint = ClipGet() MsgBox(0, "String obtained is:", $hint);To be removed later on!!! $hint1=(StringReplace($hint, "_ ", "*")) MsgBox(0, "String is now:", $hint1) ;for $i = 1 to StringLen ( $hint1 ) If StringInStr ( $hint1, " *") > 0 Then                 $letter = StringMid($hint1, (StringInStr ( $hint1, (" *"))-1),1)                 MsgBox(0, "$letter","--"& $letter &"--")     ;$hint2=StringReplace($hint1, "*"& $letter & " *", "* "& $letter &"*" )         $tosearch = $letter&chr(32)         $hint2=StringReplace($hint1, $letter , $letter) EndIf     MsgBox(0, "$hint2", $hint2)


The --H-- is replace with --H -- ( a space is in !!!)

Sorry I have to go see you later

#5 aommaster

aommaster

    Adventurer

  • Active Members
  • PipPip
  • 140 posts

Posted 30 July 2007 - 01:21 AM

Hmm... that doesn't seem to be doing what I want it to do, unless I've seriously overlooked something :)

Okay, let me see if I can rephrase my initial question:
Let's say I have an input as follows:
_ _ _ _ _ H _ _ _ B _ _ _ _ _ _

and autoit has this input stored as a string. What code do I have to use to convert the input above into the below:
***** H*** B*** ***

Basically, this is what has been done, but I don't know how to put it in code:
1.All 3 consecutive spaces are replaced with one space
2.All spaces between "_" have been removed
3.All "_" have been converted to "*"

Hope that clarifies things a little.

#6 aommaster

aommaster

    Adventurer

  • Active Members
  • PipPip
  • 140 posts

Posted 30 July 2007 - 04:00 AM

Okay... here's another thing I'd like to know.

How are strings stored in autoit? So, let's say that I use $hint = ClipGet() where the clipboard contains text. How are the strings stored in $hint? I'm thinking along the lines of getting rid of every other character in the input, which would leave me with the output I require.

I know that programming in C stores the string as an Array, but as for autoit, I have no idea.

I was thinking about using a For-Next loop, and using an nested if statement, use a Mod operator to make sure whether the number was even. But that was all based on the assumption that I am using an array, which I don't think it what is going on.

Any ideas?

#7 enaiman

enaiman

    Universalist

  • Active Members
  • PipPipPipPipPipPip
  • 1,922 posts

Posted 30 July 2007 - 04:19 AM

Try this:

$hint = ClipGet() MsgBox(0, "String obtained is:", $hint) ;To be removed later on!!! $hint1=StringStripWS(StringReplace($hint, "_", "*"), 8) MsgBox(0, "String is now:", $hint1)


This will remove all white spaces.

If you want the words separated you have to provide the algorithm for separating them. (how do you know how to separe the words? the example you gave is only a big continuous string (_ _ _ _ _ H _ _ _ B _ _ _ _ _ _). Sure it is easy to write a piece of code for this example but my guess it is you will want a code to work everytime.
So far the post is very confusing - you tried to give many explanations but that doesn't make it clear; maybe it will be a good idea to somehow rephrase the asked question.

Also, maybe it will be good to post all your code here.

Edited by enaiman, 30 July 2007 - 04:27 AM.

SNMP_UDF ... for SNMPv1 and v2c so far, GetBulk and a new example script

wannabe "Unbeatable" Tic-Tac-Toe

Paper-Scissor-Rock ... try to beat it anyway :)


#8 enaiman

enaiman

    Universalist

  • Active Members
  • PipPipPipPipPipPip
  • 1,922 posts

Posted 30 July 2007 - 04:43 AM

I guess I found the mistake:

So, each letter that has not been guessed us represented by a "_", a space between words is signified by a " ".

but in your example you have plenty of white spaces

_ _ _ _ _ H _ _ _ B _ _ _ _ _ _

try to use this string _____ H___ B___ ___
Or if you like your underscores to be separated by white spaces make it look like _ _ _ _ _ H _ _ _ B _ _ _ _ _ _ (used 3 spaces between words)

Then use your original code:

;_ _ _ _ _   H _ _ _   B _ _ _   _ _ _ $hint = ClipGet() MsgBox(0, "String obtained is:", $hint);To be removed later on!!! $hint1=StringReplace($hint, "_", "*");---> removed the white space after _ MsgBox(0, "String is now:", $hint1)


and it will do whatever you want.

Everything is a matter of how the original string is formatted - StringReplace has no bugs.

EDIT: it looks like the automatic text formatting on the forum removes the WS in excess so I've added the correct string to your code

Edited by enaiman, 30 July 2007 - 04:45 AM.

SNMP_UDF ... for SNMPv1 and v2c so far, GetBulk and a new example script

wannabe "Unbeatable" Tic-Tac-Toe

Paper-Scissor-Rock ... try to beat it anyway :)


#9 cramaboule

cramaboule

    Universalist

  • Active Members
  • PipPipPipPipPip
  • 286 posts

Posted 30 July 2007 - 09:06 AM

I find your solution !!!!

$hint = ClipGet() MsgBox(0, "String obtained is:", $hint) ;To be removed later on!!! $hint1=(StringReplace($hint, "_ ", "*")) MsgBox(0, "String is now:", $hint1) While StringInStr ( $hint1, " *") > 0                 $letter = StringMid($hint1, (StringInStr ( $hint1, (" *"))-1),1)         $hint1=StringReplace($hint1, $letter&chr(32) , Chr(32)&$letter ) WEnd MsgBox(0, "$hint2", $hint1)


#10 cramaboule

cramaboule

    Universalist

  • Active Members
  • PipPipPipPipPip
  • 286 posts

Posted 30 July 2007 - 09:21 AM

I know that programming in C stores the string as an Array, but as for autoit, I have no idea.

The Help files is really HELPFUL

You can strore how ever you want.
$hint is simply a variable
if you want an array :
myarray[0]= "123"
myarray[1]= 777
myarray[2]= $hint
myarray[3]= "hello world"

look in the help file about variable and array...

#11 aommaster

aommaster

    Adventurer

  • Active Members
  • PipPip
  • 140 posts

Posted 30 July 2007 - 06:33 PM

I guess I found the mistake:
but in your example you have plenty of white spaces


I believe that I seem to have overlooked the automatic formatting by the forum, and I think this is what may have confused many people with it. I apologise.

Let me see if I can fix this:
Letters are separated with a single space (white space)
Words are separated by THREE spaces (white spaces)

I tried out your program and it seems to remove all the white spaces from the words, which causes a problem because the program cannot count the number of words there are.

I'm actually thiking of declaring $hint as an array. Then, use a for $i to stringlen to remove ever OTHER letter, by saving every other letter into a new array. That produces the input into the form I need it in.

Thanks again!

#12 aommaster

aommaster

    Adventurer

  • Active Members
  • PipPip
  • 140 posts

Posted 30 July 2007 - 06:35 PM

You can strore how ever you want.
$hint is simply a variable

look in the help file about variable and array...


Okay! I think that's what I need then... if I can store it into an array, well, *pokes above post*, then I think I have sorted out the problem.

I also checked the code that you gave me above, and it doesn't seem to word :)

#13 cramaboule

cramaboule

    Universalist

  • Active Members
  • PipPipPipPipPip
  • 286 posts

Posted 30 July 2007 - 06:48 PM


I also checked the code that you gave me above



Well,..
_ _ _ _ _ H _ _ _ B _ _ _ _ _ _


I use the above as input

***** H*** B******

and had this as output

The problem is from the input,... how do I know where is the 4th word ?
because with what you give, it is imposible for me (and so for autoit) to know where to put the 4th word ! :)

Edited by cramaboule, 30 July 2007 - 06:50 PM.


#14 aommaster

aommaster

    Adventurer

  • Active Members
  • PipPip
  • 140 posts

Posted 30 July 2007 - 07:23 PM

I tried it with the input you gave, and yeah... it works. However, it doesn't work with the full input, which is something like this:
_ _ _ _ _   H _ _ _   B _ _ _   _ _ _ _ _   _ _   B _   _ _   _ _ _ _ _ G   _ _   F _ _ _   G _ _ _ _   _ _ _ P _ _ _


I was also working on an array method of removing every other character.

This is what I got so far:
CODE
#include <Array.au3>
MsgBox(0,"", "Press okay when ready")

dim $hint1[300]
dim $hint2[300]

$hint = ClipGet()
MsgBox(0, "String obtained is:", $hint) ;To be removed later on!!!

$hint1 = StringSplit($hint, @LF)
_ArrayDisplay($hint1)

dim $j=0
for $i=0 to stringlen($hint1)
if (Mod($i, 2)=0) Then
$hint2[$j]=$hint1[$i]
$j += 1
Endif
Next

Dim $hint3= _ArrayToString ( $hint2, "")
MsgBox(0, "String obtained is now:", $hint3)


However, when viewing the array, row 0 has a value of 1 assigned to it for some strange reason. How do I get rid of it?

Edited by aommaster, 30 July 2007 - 07:25 PM.


#15 aommaster

aommaster

    Adventurer

  • Active Members
  • PipPip
  • 140 posts

Posted 30 July 2007 - 07:48 PM

Okay...working on it a bit further, here's where I got to:
#include <Array.au3> MsgBox(0,"", "Press okay when ready") dim $hint[300] dim $hint1[300] dim $hint2[300] $hint = ClipGet() MsgBox(0, "String obtained is:", $hint)                                                 ;To be removed later on!!! $hint1 = StringSplit($hint, " ") _ArrayDisplay($hint1) Dim $hint3= _ArrayToString ( $hint1, "", 1) MsgBox(0, "String obtained is now:", $hint3)


But now...it's removing ALL of the spaces! And yeah, there may be a few unused variables, that's because they are used in the code, but i've commented them out.

#16 Manadar

Manadar

         

  • MVPs
  • 10,900 posts

Posted 30 July 2007 - 08:11 PM

I just wrote you a example, commenting along the way. You should really buff this up, as these are only the basics.

AutoIt         
Dim $gAnswer = "a ghoul in the dark" ; set up the answer Dim $gGuesses[1] = [" "]; another global variable that we will need later. Thsi will contain all guessed letters                         ; space has already been guessed so that the user will see it later While 1     $sReturn = "" ; empty the output string for future use     $sAnswerSplit = StringSplit($gAnswer,"") ; split every character into a seperate array     For $x = 1 to $sAnswerSplit[0] ; loop through the entire string         For $y = 0 to UBound($gGuesses)-1 ; also loop through all the guessed characters             If $sAnswerSplit[$x] = $gGuesses[$y] Then ; this character has been guessed                 $sReturn &= $sAnswerSplit[$x] ; put this character in the final string that the user will see                 ExitLoop             ElseIf $y = UBound($gGuesses)-1 Then ; the end of loop has been reached, so the character has not been guessed                 $sReturn &= "_" ; put a non-guessed character here             EndIf         Next     Next     If Not StringInStr($sReturn,"_") Then ; everything has been guessed         MsgBox(0, "hangman", "Congratulations you have won!!" & @CRLF & @CRLF & "The answer was: " & $gAnswer)         Exit     EndIf     $sInput = InputBox("Hangman", $sReturn & @CRLF & @CRLF & "Guess another character.") ; show the user his progress and let him guess a new character     If @error Then Exit ; the user clicked cancel     ReDim $gGuesses[UBound($gGuesses)+1] ; resize the array     $gGuesses[UBound($gGuesses)-1] = $sInput ; put the new value in and start over WEnd


Edit: Took me 20 minutes, so please thank me and tell me this is what you want. :)

Edited by Manadar, 30 July 2007 - 08:12 PM.


#17 aommaster

aommaster

    Adventurer

  • Active Members
  • PipPip
  • 140 posts

Posted 30 July 2007 - 08:28 PM

Hi!

Good news: I really appreciate you spending the time to write this program and it really helps me understand how the loops work

Bad news: I'm afraid this is not what I am looking for.

The hangman game is already available and what I want to program to effetively do is:
1.Guess a range of letters (done in the code I wrote)
2.Copy the clue into the clipboard (done)
3.Change the cllue into a form that can be compared with other strings opened from a text file (stuck here)
4.Pick the correct answer and paste it in (I have ideas on using stringcompare, etc, but I haven't reached that stage yet)

You see, the input is in the form of this:
_ _ _ _ _   H _ _ _   B _ _ _   _ _ _ _ _   _ _   B _   _ _   _ _ _ _ _ G   _ _   F _ _ _   G _ _ _ _   _ _ _ P _ _ _


And I want the program to change the above into the following, either by using string variables or using arrays (which was my second snippet of code, on page 1), change it into the below:
***** H*** B*** ***** ** B* ** *****G ** F*** G**** ***P***


This is done based on the following rules:
1._ becomes *
2.Letters are separated by single spaces, which need to be removed
3.Words are separated by three spaces, which need to be changed to only a single space

I found that if you remove every other character from the initial input string, you get the output required (without the *'s of course, which can be done easily). Only thing is, if you take a look at the last code snippet on page 1, you see that white spaces are removed. I have no idea why it happens.

Edited by aommaster, 30 July 2007 - 08:31 PM.


#18 enaiman

enaiman

    Universalist

  • Active Members
  • PipPipPipPipPipPip
  • 1,922 posts

Posted 30 July 2007 - 11:16 PM

This is working without any arrays - it just uses a temporary replacement of 3ws with a character (% in my example), strips all the white spaces and replaces the temp char % with a ws.
It will write the result in a file just to check if it is correct.

$hint = ClipGet() MsgBox(0, "String obtained is:", $hint) ;To be removed later on!!! $hint1=StringReplace($hint, "   ", "%") MsgBox(0, "String is now: after replacing 3ws", $hint1) $hint1=StringStripWS($hint1, 8) MsgBox(0, "String is now: after striping ws", $hint1) $hint1=StringReplace($hint1, "_", "*") MsgBox(0, "String is now: after replacing _ with *", $hint1) $hint1=StringReplace($hint1, "%", " ") MsgBox(0, "String is now: after replacing temp char % with ws", $hint1) $tt = FileOpen("d:\tttest.txt", 2) FileWriteLine($tt, $hint1) FileClose($tt) MsgBox(0, "Final result is:", $hint1)


this will work no matter how long your string is - the only condition is to keep 3ws between words and 1ws between letters

Cheers.

SNMP_UDF ... for SNMPv1 and v2c so far, GetBulk and a new example script

wannabe "Unbeatable" Tic-Tac-Toe

Paper-Scissor-Rock ... try to beat it anyway :)


#19 aommaster

aommaster

    Adventurer

  • Active Members
  • PipPip
  • 140 posts

Posted 30 July 2007 - 11:19 PM

This is working without any arrays - it just uses a temporary replacement of 3ws with a character (% in my example), strips all the white spaces and replaces the temp char % with a ws.
It will write the result in a file just to check if it is correct.

$hint = ClipGet() MsgBox(0, "String obtained is:", $hint) ;To be removed later on!!! $hint1=StringReplace($hint, "   ", "%") MsgBox(0, "String is now: after replacing 3ws", $hint1) $hint1=StringStripWS($hint1, 8) MsgBox(0, "String is now: after striping ws", $hint1) $hint1=StringReplace($hint1, "_", "*") MsgBox(0, "String is now: after replacing _ with *", $hint1) $hint1=StringReplace($hint1, "%", " ") MsgBox(0, "String is now: after replacing temp char % with ws", $hint1) $tt = FileOpen("d:\tttest.txt", 2) FileWriteLine($tt, $hint1) FileClose($tt) MsgBox(0, "Final result is:", $hint1)


this will work no matter how long your string is - the only condition is to keep 3ws between words and 1ws between letters

Cheers.

*slaps self*

I just cannot believe I didn't think of that!

It works PERFECTLY! Thank you very much!

#20 enaiman

enaiman

    Universalist

  • Active Members
  • PipPipPipPipPipPip
  • 1,922 posts

Posted 30 July 2007 - 11:28 PM

Glad it helped you :)

SNMP_UDF ... for SNMPv1 and v2c so far, GetBulk and a new example script

wannabe "Unbeatable" Tic-Tac-Toe

Paper-Scissor-Rock ... try to beat it anyway :)





0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users