AutoHotkey Community

It is currently May 25th, 2012, 3:43 am

All times are UTC [ DST ]




Post new topic Reply to topic  [ 14 posts ] 
Author Message
PostPosted: May 3rd, 2007, 7:16 pm 
I am trying to write a simple function to encode and decode special characters in URLs.

For example if given the following URL:

http://www.someplace.com/a%20folder/2nd%2Dfolder/

The function would return:

http://www.someplace.com/a folder/2nd-folder/

or vice-versa.

Here's what I have so far:
Code:
AutoTrim, Off
url_temp_clip = %clipboard%
Send, ^c
clipboard := RegExReplace(clipboard, "\%([0-9A-F]{2})" , hex_to_dec("0x$1"))
Send, ^v
clipboard = %url_temp_clip%
AutoTrim, On

hex_to_dec(x)
{
   Loop
      If RegExMatch(x, "i)(.*)(0x[a-f\d]*)(.*)", y)
         x := y1 . y2+0 . y3           ; convert hex numbers to decimal
      Else Break
   return x
}


In Perl the code would be something like:
Code:
$str =~ s/([^A-Za-z0-9])/sprintf("%%%02X", ord($1))/seg; # Encode string
$str =~ s/\%([A-Fa-f0-9]{2})/pack('C', hex($1))/seg; # Decode


But I can't seem to get the same thing done in AHK. Any help would be much appreciated.


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: May 3rd, 2007, 7:17 pm 
Offline
User avatar

Joined: August 30th, 2005, 8:43 pm
Posts: 8647
Location: Salem, MA
I have seen scripts for this - did you search the forum?

_________________
Image
(Common Answers) - New Tutorials Forum - Humongous FAQ


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: May 3rd, 2007, 7:20 pm 
Yes. I tried searching for things like:

URL encode
URL decode
Hex decode
convert URL

Found some things that were similar but not what I was looking for.


Report this post
Top
  
Reply with quote  
PostPosted: May 3rd, 2007, 7:41 pm 
Offline
User avatar

Joined: August 11th, 2004, 1:47 am
Posts: 5346
Location: UK
Here are two functions:

Code:
uriDecode(str) {
   Loop
      If RegExMatch(str, "i)(?<=%)[\da-f]{1,2}", hex)
         StringReplace, str, str, `%%hex%, % Chr("0x" . hex), All
      Else Break
   Return, str
}

uriEncode(str) {
   f = %A_FormatInteger%
   SetFormat, Integer, Hex
   If RegExMatch(str, "^\w+:/{0,2}", pr)
      StringTrimLeft, str, str, StrLen(pr)
   StringReplace, str, str, `%, `%25, All
   Loop
      If RegExMatch(str, "i)[^\w\.~%]", char)
         StringReplace, str, str, %char%, % "%" . Asc(char), All
      Else Break
   SetFormat, Integer, %f%
   Return, pr . str
}

e.g. MsgBox, % uriDecode("http://www.someplace.com/a%20folder/2nd%2Dfolder/")

_________________
GitHubScriptsIronAHK Contact by email not private message.


Report this post
Top
 Profile  
Reply with quote  
 Post subject: Thanks!
PostPosted: May 3rd, 2007, 7:50 pm 
Exactly what I'm looking for. Thanks for the quick response!


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: May 3rd, 2007, 7:59 pm 
Offline
User avatar

Joined: December 26th, 2005, 4:40 pm
Posts: 8775
@Titan. Nice pair of useful functions. :)


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: May 4th, 2007, 10:09 pm 
I made some modifications to get the shortcut I was trying to create. Here is the code in case anyone is interested.
Code:
^!+5::
   AutoTrim, Off
   url_temp_clip = %clipboard%
   Send, ^c
   IfInString, clipboard, `%
   {
      clipboard := uriDecode(clipboard)
   }
   else
   {
      clipboard := uriEncode(clipboard)
   }
   Send, ^v
   clipboard = %url_temp_clip%
   AutoTrim, On
return

uriDecode(str)
{
   ; Find uri encoded characters such as %20 (space) and replace with ascii character

   pos = 1
   Loop
      If pos := RegExMatch(str, "i)(?<=%)[\da-f]{2}", hex, pos++)
         StringReplace, str, str, `%%hex%, % Chr("0x" . hex), All
      Else Break
   Return, str
}

uriEncode(str)
{
   ; Replace characters with uri encoded version except for letters, numbers,
   ; and the following: /.~:&=-

   f = %A_FormatInteger%
   SetFormat, Integer, Hex
   pos = 1
   Loop
      If pos := RegExMatch(str, "i)[^\/\w\.~`:%&=-]", char, pos++)
         StringReplace, str, str, %char%, % "%" . Asc(char), All
      Else Break
   SetFormat, Integer, %f%
   StringReplace, str, str, 0x, , All
   Return, str
}


Report this post
Top
  
Reply with quote  
 Post subject: Odd...
PostPosted: June 15th, 2007, 3:27 am 
Offline

Joined: May 15th, 2007, 3:43 am
Posts: 2
Strange, when I run the uriEncode() function that Titan posted, I had the following problems:

1) It was encoding characters that didn't need to be encoded. In my case, these were colons (:) and forward slashes (/).

2) It was outputting hex character numbers with a 0x at the beginning, which is consistent with what the SetFormat documentation says regarding hexadecimal format:

Quote:
Hexadecimal numbers all start with the prefix 0x (e.g. 0xA9).


So I modified the function slightly, here is the result:

Code:
uriEncode(str) {
   f = %A_FormatInteger%
   SetFormat, Integer, Hex
   If RegExMatch(str, "^\w+:/{0,2}", pr)
      StringTrimLeft, str, str, StrLen(pr)
   StringReplace, str, str, `%, `%25, All
   Loop
      If RegExMatch(str, "i)[^\w\.~%/:]", char)
         StringReplace, str, str, %char%, % "%" . SubStr(Asc(char),3), All
      Else Break
   SetFormat, Integer, %f%
   Return, pr . str
}


The second RegExMatch() now ignores colons and forward slashes, and the Asc() function is now wrapped with a SubStr that strips the extra characters.

Please note that I made no attempt at a universal fix: I just modified the parts that were causing problems in my specific and very limited usage of this function.

Thanks for posting the original code, Titan!

PS: I'm a AutoHotKey noob, so I'm probably missing something obvious that would explain why I was having problems with the function in the first place. I'm just posting this in case someone else has the same problems that I was having.


Report this post
Top
 Profile  
Reply with quote  
PostPosted: April 21st, 2010, 6:22 pm 
Hello,

I'm having trouble figuring out one of the two regular expressions that Titan used in his code. I'd like to modify his code somewhat, and I need to figure out what is going on first.

The code in question is at the heart of the encoding function:
Code:
If RegExMatch(str, "i)[^\w\.~%]", char)
   StringReplace, str, str, %char%, % "%" . Asc(char), All


It looks to me like that regular expression would match any single character that isn't whitespace, a period, a ~, or a %. Wouldn't this catch every single alphanumeric character?

It seems like better code would be to insert an escape character before the caret to remove its special meaning:
Code:
If RegExMatch(str, "i)[\^\w\.~%]", char)
   StringReplace, str, str, %char%, % "%" . Asc(char), All


Am I missing something? Was Titan's code for an older version of the PCRE lib in which carets didn't have a special meaning?


Report this post
Top
  
Reply with quote  
PostPosted: April 21st, 2010, 6:42 pm 
Offline
User avatar

Joined: March 19th, 2008, 12:43 am
Posts: 5461
Location: the tunnel(?=light)
JoeSchmoe wrote:
It looks to me like that regular expression would match any single character that isn't whitespace, a period, a ~, or a %.


That should be any single character that isn't a word character (isn't an alphanumeric character), a literal period, a ~ or a %.

_________________
Image
Try Quick Search for Autohotkey or see the tutorial for newbies.


Report this post
Top
 Profile  
Reply with quote  
PostPosted: November 6th, 2010, 2:40 pm 
Offline

Joined: November 6th, 2010, 2:34 pm
Posts: 3
Location: Atlanta, GA, USA
I am trying to convert a string of csv text to URL-format to be posted using uriEncode and httpQuery together.
I am able to post simple strings using the code below, but not an example like shown -- I suspect it might be the % signs???
Admittedly a newbie to ahk and assistance much appreciated.

Code:
#noenv
uriEncode(str)
{
   ; Replace characters with uri encoded version except for letters, numbers,
   ; and the following: /.~:&=-

   f = %A_FormatInteger%
   SetFormat, Integer, Hex
   pos = 1
   Loop
      If pos := RegExMatch(str, "i)[^\/\w\.~`:%&=-]", char, pos++)
         StringReplace, str, str, %char%, % "%" . Asc(char), All
      Else Break
   SetFormat, Integer, %f%
   StringReplace, str, str, 0x, , All
   Return, str
}

estring = 2010,11,5,18,0,55,"ROC177262","CPSOS - Search - Search",""2010,11,5,18,1,0,"ROC177262","Logon

status",""2010,11,5,18,1,6,"ROC177262","AT&T U-Verse CRM Customer Interaction Manager : Release 14 -

csrPG4cmem105",""2010,11,5,18,1,9,"ROC177262","AT&T Wireline - Synchronoss Technologies, Inc. - Windows Inter - \\Remote, 128-bit SSL/TLS.",""

newstring = % uriEncode(estring)
msgbox, %newstring% ;valid conversion confirmed here

html     := ""
URL      := "http://www.mysite.com/act_raw_upload.cfm"
POSTData := "raw_data= %newstring%"

length := httpQuery(html,URL,POSTdata)
varSetCapacity(html,-1)
   
#include httpQuery.ahk


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: November 6th, 2010, 6:25 pm 
Offline
User avatar

Joined: October 7th, 2006, 8:45 am
Posts: 3328
Location: Simi Valley, CA
Instead of
Code:
POSTData := "raw_data= %newstring%"

try
Code:
POSTData := "raw_data=" newstring


and take a look at FAQ: When exactly are variable names enclosed in percent signs?

_________________
Ternary (a ? b : c) guide     TSV Table Manipulation Library
Post code inside [code][/code] tags!


Report this post
Top
 Profile  
Reply with quote  
PostPosted: November 7th, 2010, 1:45 am 
Offline

Joined: November 6th, 2010, 2:34 pm
Posts: 3
Location: Atlanta, GA, USA
Many thanks VxE.
I also found that switching to the later post/mod of the uriEncoder by Ageless sealed the deal.

One more humble request: How would you modify the Ageless code below to encode CR/LF characters in the source string? I'm a challenged with code as terse as this stuff.

Code:
uriEncode(str) {
   f = %A_FormatInteger%
   SetFormat, Integer, Hex
   If RegExMatch(str, "^\w+:/{0,2}", pr)
      StringTrimLeft, str, str, StrLen(pr)
   StringReplace, str, str, `%, `%25, All
   Loop
      If RegExMatch(str, "i)[^\w\.~%/:]", char)
         StringReplace, str, str, %char%, % "%" . SubStr(Asc(char),3), All
      Else Break
   SetFormat, Integer, %f%
   Return, pr . str
}


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: April 2nd, 2012, 7:04 pm 
Offline

Joined: February 6th, 2007, 12:30 am
Posts: 142
Location: Michigan
I found a small bug in the earlier code. I was using it to encode strings for a slightly different purpose than just url encoding.

The bug: any character that encodes as a single hex character (like linefeed = 0xA) is not zero filled and should be 0x0A so that it will decode correctly later.

Here is the change I made to ensure the hex value is zerofilled. Others may find a better or more efficient way, but this does work when you have newline characters.

Code:
;============================================================
; encode special characters in a string (usually for url encoding)
;============================================================

fn_encode(str) {
   f = %A_FormatInteger%
   SetFormat, Integer, Hex   ; set integer format to hex
   
   If RegExMatch(str, "^\w+:/{0,2}", pr)   
      StringTrimLeft, str, str, StrLen(pr)
   
   StringReplace, str, str, `%, `%25, All    ; replace all % with %25
   
   Loop
      If RegExMatch(str, "i)[^\w\.~%/:]", char)    ; exclude alphnumeric . ~ % / :
         StringReplace, str, str, %char%, % "%" . fn_zerofill(SubStr(Asc(char),3),2) , All
      Else Break
   
   SetFormat, Integer, %f%   ; restore integer format
   Return, pr . str
}

;============================================================
; decode encoded string
;============================================================

fn_decode(str) {
    Loop
        If RegExMatch(str, "i)(?<=%)[\da-f]{1,2}", hex)
            StringReplace, str, str, `%%hex%, % Chr("0x" . hex), All
        Else Break
    Return, str
}

;-------------------------------------
; example call to zerofill
; n := zerofill(n, 3)
;-------------------------------------

fn_zerofill(num, size){   ; returns num zerofilled to size digits
    StringLen, length, num
    c := size - length
    loop, %c%
        num := "0" num
    return num
}

_________________
http://www.panofish.net


Report this post
Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 14 posts ] 

All times are UTC [ DST ]


Who is online

Users browsing this forum: lblb, Leef_me and 19 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