AutoHotkey Community

It is currently May 27th, 2012, 8:18 am

All times are UTC [ DST ]




Post new topic Reply to topic  [ 78 posts ]  Go to page 1, 2, 3, 4, 5, 6  Next
Author Message
PostPosted: March 3rd, 2006, 8:04 am 
Online
User avatar

Joined: December 26th, 2005, 4:40 pm
Posts: 8776
    StringMod() was originally posted in General Chat topic Numerology .

  • PhiLho enhanced the original code & included Replace, Rot13 and Rot47
  • Titan re-wrote the function and enhanced it with Scramble, Bloat, Pattern.

    Function StringMod() extracts, excludes or replaces specified characters from the String passed on to it and returns
    the modified string. It can also flip a string (reversed order) or convert it into Rot13 and Rot47.
    Additional functionality are detailed below.

    Usage: StringMod(string, method [, param1, param2])
Quote:
    String Modification: Methods with examples

    Methods:

      Only
      Omit
      Flip
      Replace
      Rot13
      Rot47
      Scramble
      Bloat
      Pattern
    Examples:

    Extract the Vowels from the name "Goyyah"
    StringMod("Goyyah","Only","AEIOU") returns "oa"

    Extract the Consonants from the name "Goyyah"
    StringMod("Goyyah","Omit","AEIOU") returns "Gyyh"

    Flips "Goyyah"
    StringMod("Goyyah","Flip") returns "hayyoG"

    Replace "*^" in "^H*e*l*l*o^" with "_"
    StringMod("^H*e*l*l*o^", "Replace" , "*^" , "_") returns "_H_e_l_l_o_"

      Example for Validating a String into Filename
    Code:
    filename = This?Is?\A:/<"Valid"File>*Name?.txt
    invalidFilenameCharacters=\/:*?"<>|
    Msgbox, % StringMod(filename, "Replace", invalidFilenameCharacters)
    ; This_Is_A___Valid_File__Name_.txt


    Convert "HELLO" into Rot13
    StringMod("Hello", "Rot13") returns "UYRRB"

    Convert "HELLO" into Rot47
    StringMod("Hello", "Rot47") returns "wt{{~"

    Scramble the word "AUTOHOTKEY"
    StringMod("AUTOHOTKEY","Scramble") will return something like "UKOTTOEAHY"

    • Laszlo's CharPerm() - similar functionality - optimised

    Stuff Characters before and after each character in the word "Autohotkey"
    StringMod("AutoHotkey","Bloat", "{" , "}" ) returns "{A}{u}{t}{o}{H}{o}{t}{k}{e}{y}"


    Pattern may be used to find the Anagrammatical relationship between two words.
    Pattern returns a String arranged in alphabetical order in such
    a way that
    the number of occurences follows each letter

      Pattern1 := StringMod("RACE","Pattern") ; "A1C1E1R1"
      Pattern2 := StringMod("CARE","Pattern") ; "A1C1E1R1"
      If Pattern1 = %Pattern2%
      ; evaluates to a logical true because both Pattern1 and Pattern2 share the same pattern "A1C1E1R1"





Image

_________________
URLGet - Internet Explorer based Downloader
StartEx - Portable Shortcut Link


Last edited by SKAN on June 16th, 2008, 2:09 pm, edited 17 times in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 3rd, 2006, 9:31 am 
Online
User avatar

Joined: December 26th, 2005, 4:40 pm
Posts: 8776
Other String Manipulation Functions

StringSlice() : Added 2006-March-19.

Quote:
StringSlice() : Similar to AHK's StringSplit Command - However, with one difference.
String is Split, based on defined width rather than a delimiter

    Example: StringSlice("Dictionary", 3, "Var") will initialise 5 Variables: Var0 through Var4

    Var0 will contain 4
    Var1 will contain "Dic"
    Var2 will contain "tio"
    Var3 will contain "nar"
    Var4 will contain "y"

Regards, :)

_________________
URLGet - Internet Explorer based Downloader
StartEx - Portable Shortcut Link


Last edited by SKAN on March 19th, 2006, 1:24 pm, edited 5 times in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 3rd, 2006, 11:39 am 
Offline

Joined: December 27th, 2005, 1:46 pm
Posts: 6837
Location: France (near Paris)
Thanks for the credit :-)
For consistency, I would have integrated Flip into the loop:
Code:
   Loop Parse, _string
   {
      If (_mode = "Flip")
      {
         rStr := A_LoopField rStr
      }
      ; Is char in the given list?
      Else IfInString _chars, %A_LoopField%
      {
         If (_mode = "Only")
            rStr := rStr A_LoopField
         Else If (_mode = "Replace")
            rStr := rStr _replCh
      }
      Else
      {
         If (_mode = "Omit" or _mode = "Replace")
            rStr := rStr A_LoopField
      }
   }

Also I believe that the Flip code you gave may give bad results if the string has spaces (in default mode).
Such Flip function is probably not of huge utility, except perhaps to perform some AHK functions that doesn't provide a facility starting from the right of the string.

_________________
Image vPhiLho := RegExReplace("Philippe Lhoste", "^(\w{3})\w*\s+\b(\w{3})\w*$", "$1$2")


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 3rd, 2006, 12:21 pm 
Offline

Joined: December 27th, 2005, 1:46 pm
Posts: 6837
Location: France (near Paris)
Another transformation: Rot13, Rot47 and variants.
File can be downloaded from AutoHotkey.net.
Code:
StringMod(_string, _mode="", _chars="", _replCh="")
{
   local rStr, char, ascii, o

   ; Defaults
   If _mode not in Omit,Only,Replace,Flip,Rot13,Rot47
      _mode = Omit
   If _chars =
   {
      If _mode = Rot13
         _chars = 13
      Else If _mode = Rot47
         _chars = 47
      Else
         _chars = %A_Space%
   }
   If _replCh =
      _replCh = _

   Loop Parse, _string
   {
      If (_mode = "Flip")
      {
         rStr := A_LoopField rStr
      }
      Else If (_mode = "Rot13")
      {
         char := Asc(A_LoopField)
         ; o is 'A' code if it is an uppercase letter, and 'a' code if it is a lowercase letter
         o := Asc("A") * (Asc("A") <= char && char <= Asc("Z")) + Asc("a") * (Asc("a") <= char && char <= Asc("z"))
         If (o > 0)
         {
            ; Set between 0 and 25, add rotation factor, modulus alphabet size
            char := Mod(char - o + _chars, 26)
            ; Transform back to char, upper or lower
            char := Chr(char + o)
         }
         Else
         {
            ; Non alphabetic, unchanged
            char := A_LoopField
         }
         rStr := rStr char
      }
      Else If (_mode = "Rot47")
      {
         char := A_LoopField
         If char between ! and ~
         {
            char := Asc(A_LoopField)
            ; Set between 0 and 93, add rotation factor, modulus range size
            char := Mod(char - 33 + _chars, 94)
            ; Transform back to char
            char := Chr(char + 33)
         }
         rStr := rStr char
      }
      ; Is char in the given list?
      Else IfInString _chars, %A_LoopField%
      {
         If (_mode = "Only")
            rStr := rStr A_LoopField
         Else If (_mode = "Replace")
            rStr := rStr _replCh
      }
      Else
      {
         If (_mode = "Omit" or _mode = "Replace")
            rStr := rStr A_LoopField
      }
   }
   Return rStr
}

; Run test code only if the file is ran standalone
If (A_ScriptName = "StringMod.ahk")
{

str = The name of the variable whose contents will be analyzed.
filename = This?Is?\A:/<"Valid"File>*Name?.txt
invalidFilenameCharacters=\/:*?"<>|
r = |
r := r StringMod(str, "OMIT", " ") "|`n|"
r := r StringMod(str, "Omit", "aeiouy") "|`n|"
r := r StringMod(str, "only", " ") "|`n|"
r := r StringMod(str, "Only", "aeiouy ") "|`n"
r := r StringMod(str, "RePlAcE", " ") "|`n|"
r := r StringMod(str, "Replace", "aeiouy", "$") "|`n|"
r := r StringMod(str, "Flip") "|`n|"
r := r StringMod(str, "Rot13") "|`n|"
r := r StringMod(str, "Rot13", 11) "|`n|"
r := r StringMod(str, "Rot47") "|`n|"
r := r StringMod(str, "Rot47", 33) "|`n|"
r := r StringMod(filename, "Omit", invalidFilenameCharacters) "|`n|"
r := r StringMod(filename, "Replace", invalidFilenameCharacters) "|`n|"
r := r StringMod(filename, "Replace", invalidFilenameCharacters, " Fun ") "|`n"
MsgBox %r%
a1 := StringMod(str, "Rot13")
b1 := StringMod(a1, "Rot13")
a2 := StringMod(str, "Rot13", 7)
b2 := StringMod(a2, "Rot13", 26-7)
MsgBox Rot13:`n%str%`n%a1%`n%b1%`n%a2%`n%b2%
a1 := StringMod(str, "Rot47")
b1 := StringMod(a1, "Rot47")
a2 := StringMod(str, "Rot47", 13)
b2 := StringMod(a2, "Rot47", 94-13)
MsgBox Rot47:`n%str%`n%a1%`n%b1%`n%a2%`n%b2%

}

_________________
Image vPhiLho := RegExReplace("Philippe Lhoste", "^(\w{3})\w*\s+\b(\w{3})\w*$", "$1$2")


Last edited by PhiLho on March 4th, 2006, 4:09 pm, edited 3 times in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 3rd, 2006, 4:34 pm 
Offline

Joined: February 14th, 2005, 4:05 pm
Posts: 4710
Location: Boulder, CO
Nice functions!
…you could save a few lines at setting "o", with Shimanov's trick
Code:
o := 65*(64<char && char<91)+97*(96<char && char<123)


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 3rd, 2006, 5:12 pm 
Offline

Joined: December 27th, 2005, 1:46 pm
Posts: 6837
Location: France (near Paris)
Thanks!
I like the If char between 65 and 87 as it was quite readable.
But I like the logic behind the expression, and using Asc calls, it is self-documenting (more or less!). And since this function is growing, saving some lines isn't too bad.
It is perhaps a bit slower, calling Asc 6 times on each loop, but I doubt it is noticeable, we rarely Rot13 whole books...

_________________
Image vPhiLho := RegExReplace("Philippe Lhoste", "^(\w{3})\w*\s+\b(\w{3})\w*$", "$1$2")


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 3rd, 2006, 8:50 pm 
Online
User avatar

Joined: December 26th, 2005, 4:40 pm
Posts: 8776
Dear PhiLho, :)

Rot13, Rot47 and variants: :shock: I admit that I never knew about it, Thanks for Info + Function


You wrote:
For consistency, I would have integrated Flip into the loop:


I have in my mind of adding more functionality to StringMod() like

StringMod(String,"Upper")
StringMod(String,"Lower")
StringMod(String,"Title")
or StringMod(String,"Proper")


which does not require the string parsing loop & so I thought FLIP may stay out of the parsing loop.

More functionality can be added, like

StringMod(String,"OnlyDigits") ; _chars should be assigned 0123456789
StringMod(String,"A2Z") ; _chars should be assigned ABCDEFGHIJKLMNOPQRSTUVWXYZ

Instead of the present way

StringMod(String,"Only","0123456789")
StringMod(String,"Only","ABCDEFGHIJKLMNOPQRSTUVWXYZ"


Also, I am thinking about consolidating independent AHK string commands into a few but powerful functions like
writing one single function StringGet() for
StringGet(String,"Right",1)
StringGet(String,"Left",1)
StringGet(String,"Middle",10,1)

etc.

You wrote:
Flip function is probably not of huge utility, except perhaps to perform some AHK functions that doesn't provide a facility starting from the right of the string


Yes! I agree Flip is a fancy option, but maybe it will be useful for those writing word based games in AHK ( like me :wink:).

Regards, :)
Note: If anybody interested in Anagram/Jumbled word finder let me know. I've written a function for it

_________________
URLGet - Internet Explorer based Downloader
StartEx - Portable Shortcut Link


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 3rd, 2006, 9:25 pm 
Offline

Joined: February 14th, 2005, 4:05 pm
Posts: 4710
Location: Boulder, CO
Goyyah wrote:
StringGet(String,"Right",1)
StringGet(String,"Left",1)
StringGet(String,"Middle",10,1)
You could even save the second parameter. Specify the start and end character index, where a negative index should mean counting from the end. If you call it with 2 parameters, StringGet(String,3) = StringGet(String,1,3), that is, "3 chars from Left"; or StringGet(String,-2) = StringGet(String,-2,-1), that is, "2 chars from Right". I used these in the list manipulation library.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 3rd, 2006, 9:55 pm 
Online
User avatar

Joined: December 26th, 2005, 4:40 pm
Posts: 8776
Dear Laszlo, :)

Offtopic: I just visited List manipulation functions. I am yet to get comfortable with Listview but your functions will be of a great help to me!

You wrote:
You could even save the second parameter. Specify the start and end character index, where a negative index should mean counting from the end.If you call it with 2 parameters,
StringGet(String,3) = StringGet(String,1,3), that is, "3 chars from Left"; or
StringGet(String,-2) = StringGet(String,-2,-1), that is, "2 chars from Right".
I used these in the list manipulation library.


Thats a good idea!. What do you suggest for StringMid()

Regards, :)

_________________
URLGet - Internet Explorer based Downloader
StartEx - Portable Shortcut Link


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 3rd, 2006, 10:26 pm 
Offline
User avatar

Joined: August 11th, 2004, 1:47 am
Posts: 5347
Location: UK
Nice funciton :)
Here is my improved rewrite - it works slightly faster, is smaller in code size and supports character rotation of n, Flip, Omit, Replace and Only (the first few lines is for demonstration):
Code:
str = The name of the variable whose contents will be analyzed.
r := "Flip:`t" . StringMod(str, "Flip") . "`nOmit "" "":`t"
   . StringMod(str, "Omit", " ")   . "`nRot13:`t" . StringMod(str, "Rot13")
   . "`nRot47:`t" . StringMod(str, "Rot47") . "`nOnly ..:`t" . StringMod(str, "only", "aeiou")
MsgBox, 64, StringMod(), Original:`t%str%`n`n%r%

StringMod(s, m="", ch="", rc="") { ; enhanced by Titan :)
   xAT := A_AutoTrim
   AutoTrim, Off
   IfEqual, ch, , SetEnv, ch, %A_Space%
   IfEqual, rc, , SetEnv, rc, _
   Loop Parse, s
      If InStr(m, "Rot") {
         StringReplace, n, m, Rot
         l := Asc(A_LoopField)
         Loop, 2 {
            If (A_Index = 1) {
               f = 65
               c = 90
            } Else {
               f = 97
               c = 122
            } If (l >= f and l <= c) {
               l += n
               Loop
                  If (l > c)
                     l := l - c + f - 1
                  Else
                     Break
            } }
            e := e . Chr(l)
      } Else If m =Flip
         e =%A_LoopField%%e%
      Else
         If InStr(ch, A_LoopField) {
            If m =Only
               e =%e%%A_LoopField%
            Else If m =Replace
               e = %e%%rc%
         } Else If m !=Only
               e =%e%%A_LoopField%
   Autotrim, % xAT
   Return, e
}


Edit: updated rotation algorithm

_________________
GitHubScriptsIronAHK Contact by email not private message.


Last edited by polyethene on March 4th, 2006, 1:50 pm, edited 1 time in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 3rd, 2006, 10:54 pm 
Online
User avatar

Joined: December 26th, 2005, 4:40 pm
Posts: 8776
Dear Titan
Image
Great work!

_________________
URLGet - Internet Explorer based Downloader
StartEx - Portable Shortcut Link


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 3rd, 2006, 11:00 pm 
Online
User avatar

Joined: December 26th, 2005, 4:40 pm
Posts: 8776
Every String in my Original Code has been modified :?: :!: except for the function name StringMod()

Regards :D :D :D

_________________
URLGet - Internet Explorer based Downloader
StartEx - Portable Shortcut Link


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 3rd, 2006, 11:31 pm 
Offline
User avatar

Joined: August 11th, 2004, 1:47 am
Posts: 5347
Location: UK
Goyyah wrote:
Every String in my Original Code has been modified :?: :!: except for the function name StringMod()
Yep, it was a complete rewrite :) thanks for the credit.
Btw. that smilie icon is awesome :D

_________________
GitHubScriptsIronAHK Contact by email not private message.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 4th, 2006, 1:17 pm 
Online
User avatar

Joined: December 26th, 2005, 4:40 pm
Posts: 8776
Dear Titan,

StringMod("HELLO","Rot13")

should return "URYYB"

whereas

it returns "URYY\"

Please clarify..

Also, I want to put a link for a downloadable .AHK in the first post,
so please host it and provide me a link to the same.

Regards, :)

Edit: Titan updated his code

_________________
URLGet - Internet Explorer based Downloader
StartEx - Portable Shortcut Link


Last edited by SKAN on March 4th, 2006, 2:10 pm, edited 1 time in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 4th, 2006, 1:38 pm 
Offline

Joined: December 27th, 2005, 1:46 pm
Posts: 6837
Location: France (near Paris)
Well, Titan's code is short and al, but it doesn't do true Rot13, which acts only on alphabetic characters and replaces them only by alphabetic chars...
So it won't decode Rot13-encoded secret messages given on Usenet (or elsewhere).

_________________
Image vPhiLho := RegExReplace("Philippe Lhoste", "^(\w{3})\w*\s+\b(\w{3})\w*$", "$1$2")


Report this post
Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 78 posts ]  Go to page 1, 2, 3, 4, 5, 6  Next

All times are UTC [ DST ]


Who is online

Users browsing this forum: Aravind, sks, Stigg and 12 guests


You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group