Jump to content

Multiple Character Replacement


 Share

Recommended Posts

Is there a quick way of writing a string similar to what is used in the SEND command.

Example:

$myString= "{TAB 14}FooWidget{TAB 6}" 

rather than:

$myString= "                                                        FooWidget                        "

and 

$mString= "{ENTER 12}" 

rather than

$mystring= @CR&@CR&@CR&@CR&@CR&@CR&@CR&@CR&@CR&@CR&@CR&@CR

 

Link to comment
Share on other sites

@pseakins is right ;)

#include <String.au3>
Global $mystring
$mystring = _StringRepeat(@TAB, 14) & 'FooWidget' & _StringRepeat(@TAB, 6)
ConsoleWrite($mystring & @CRLF)
$mystring = _StringRepeat(@CR, 12)
ConsoleWrite($mystring & @CRLF)

 

Musashi-C64.png

"In the beginning the Universe was created. This has made a lot of people very angry and been widely regarded as a bad move."

Link to comment
Share on other sites

For the fun:

; Global $strTest = "{TAB 14}FooWidget{TAB 6}"
; Global $strTest = "{TAB 2}FooWidget{SPACE 6}"
Global $strTest = "{ENTER 4}FooWidget{TAB 2}{SPACE 4}"

ConsoleWrite("Before: '" & $strTest & "'" & @CRLF & _
             "After: '" & SendFuncToString($strTest) & "'" & @CRLF)

Func SendFuncToString($strSendCommand)

    Local $arrResult, _
          $strPatternToReplace, _
          $strCharToRepeat, _
          $intNumberOfRepeats, _
          $strReplacement


    $arrResult = StringRegExp($strSendCommand, '\{(\w+)\s(\d+)\}', $STR_REGEXPARRAYGLOBALMATCH)

    For $i = 0 To UBound($arrResult) - 1 Step 2

        $strPatternToReplace = $arrResult[$i] & '\s' & $arrResult[$i + 1]

        Switch $arrResult[$i]
            Case "SPACE"
                $strCharToRepeat = Chr(32)
            Case "ENTER"
                $strCharToRepeat = @CRLF
            Case "TAB"
                $strCharToRepeat = @TAB
            Case Else
                ContinueLoop
        EndSwitch

        $intNumberOfRepeats = $arrResult[$i + 1]

        For $j = 1 To $intNumberOfRepeats Step 1
            $strReplacement &= $strCharToRepeat
        Next

        $strSendCommand = StringRegExpReplace($strSendCommand, '{' & $strPatternToReplace & '}', $strReplacement)

        $strReplacement = ""

    Next

    Return $strSendCommand

EndFunc

^_^

Edited by FrancescoDiMuro

Click here to see my signature:

Spoiler

ALWAYS GOOD TO READ:

 

Link to comment
Share on other sites

Hi everybody :)
It's interesting to have a look at the evolution of the code concerning _StringRepeat() , code found in the include file String.au3 . Before opening the au3 file, I thought that it would be as simple as this :

Func _StringRepeat($sString, $iRepeatCount)
    Local $sResult = ""
    For $iCount = 1 To $iRepeatCount
        $sResult &= $sString
    Next
    Return $sResult
EndFunc   ;==>_StringRepeat

That's (nearly) the code written by Jeremy Landes and found in AutoIt version 3.3.8.1 (29th January, 2012)

A bit later, @guinness optimised this code in version 3.3.10.0 (23rd December, 2013) by scripting it like that (which is the actual version) :

Func _StringRepeat($sString, $iRepeatCount)
    ...
    Local $sResult = ""
    While $iRepeatCount > 1
        If BitAND($iRepeatCount, 1) Then $sResult &= $sString
        $sString &= $sString
        $iRepeatCount = BitShift($iRepeatCount, 1)
    WEnd
    Return $sString & $sResult
EndFunc   ;==>_StringRepeat

Not only some ms were gained with this optimisation, but it's interesting to have a look at the Console with a couple of examples :

_StringRepeat("+-", 16)

16  0   +-+-   8   
8   0   +-+-+-+-   4   
4   0   +-+-+-+-+-+-+-+-   2   
2   0   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-   1

_StringRepeat("+-", 21)

21  1   +-+-   10   +-
10  0   +-+-+-+-   5   +-
5   1   +-+-+-+-+-+-+-+-   2   +-+-+-+-+-
2   0   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-   1   +-+-+-+-+-

1st  column : $iRepeatCount, at the beginning of the loop
2nd column : BitAnd, returns 0 or 1 depending on $iRepeatCount being even or odd
3rd column : $sString, after its concatenation within the loop (doubling)
4th column : $iRepeatCount, after its Bitshift within the loop (halving)
5th column : $sResult, updated only when BitAnd() returned 1

There is no 5th column in example _StringRepeat("+-", 16) because all BitAnd's returned 0
That's an interesting way to study BitShift and BitAnd, especially focusing on this line :

If BitAND($iRepeatCount, 1) Then $sResult &= $sString

Thanks @guinness and a happy new year to all of you :)

Link to comment
Share on other sites

10 hours ago, pixelsearch said:

look at the evolution of the code concerning _StringRepeat()

Thanks @pixelsearch that is very interesting, the BITAND is a great technique. In the eighties I wrote a consignment note retrieval system for a national courier company and needed to use techniques like this as I had to be able to quickly access a con-note film index number from one of 1.4 million positions. We only had a 20Mb disk and the multi user Z80 based system only had 48k of RAM per user. This was written in compiled Oasis Basic. Those were the days. All the con-notes were on microfilm and the retrieval console interfaced to an automated Bell & Howell (or was it Canon (?)) viewer. The system had 512MB  of RAM and supported up to 8 users on Wyse 50 terminals.

Phil Seakins

Link to comment
Share on other sites

17 hours ago, pixelsearch said:

That's an interesting way to study BitShift and BitAnd

BTW to understand how the function works by itself it could also be helpful to translate the not-so-obvious bitwise klingon to usual numeric operations  :D

Func _StringRepeat($sString, $iRepeatCount)
    Local $sResult = ""
    While $iRepeatCount > 1
     ;   If BitAND($iRepeatCount, 1) Then $sResult &= $sString
        If Mod($iRepeatCount, 2) Then $sResult &= $sString
        $sString &= $sString
    ;    $iRepeatCount = BitShift($iRepeatCount, 1)
        $iRepeatCount = Int($iRepeatCount/2) 
    WEnd
    Return $sString & $sResult
EndFunc   ;==>_StringRepeat

 

Link to comment
Share on other sites

6 hours ago, mikell said:

the not-so-obvious bitwise klingon :D

Thanks mikell for the "translation"
Before writing my 1st post, I used an empiric way to understand better how $sResult was populated within the BitShift line, based on a pic of ... 1703 (Leibniz binary system, 1703)

1127550630_binary21.png.6c0eb4ea98e1e2976e63cdb2016ec1be.png

_StringRepeat("+-", 21) is the 2nd example in my precedent post and when we look at the pic above, it's easier to understand what's happening when guinness code is executed.

Each time BitShift is encountered, then the bit on the right is lost. It's not a problem when this bit was 0 but it certainly is when the bit was 1 !

21 = "10101" in binary system, which means we'll have a problem with both magenta & blue "1"

* Magenta 1 corresponds to a real decimal incrementation of 1, as it's the rightmost bit in 21. Losing it means we have to add one "+-" to the final result. That's how  $sResult starts to be populated.

* Blue 1 is more tricky. At the moment it's analysed (i.e. when $iRepeatCount = 5, which is "101" in binary) then this blue 1 on the right corresponds to the blue 1 in 21, which was in the middle of "10101".
Dropping it (BitShift) when 5 is analysed means you got to add 4 "+-" to $sResult. Why 4 ?
Because 4 is "100" in binary

To make it simpler, maybe it's easier to say that :
21 = "10101", i.e. "10000" + "101" (binary)
"10000" (16) will populate $sString, which is constantly concatened (doubled) in the loop
"101" (5) will populate $sResult in 2 times (1 + 4) as explained just above

It should be the same logic for any number, for example "1000111100001111"
* Replace all insides 1 with 0 => "1000000000000000" : the value of this number will "populate" $sString
* The value of the inside part, starting with 1, i.e. "111100001111" will "populate" $sResult

That's why both variables are required in guiness code, which has to Return $sString & $sResult

Edited by pixelsearch
forgot a smiley
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...