A function for Char by Char examination?

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
TXShooter
Posts: 165
Joined: 13 Dec 2017, 09:27

A function for Char by Char examination?

10 Jul 2020, 10:04

Either I'm not using the proper search terms, or this is far more illusive than I would've thought.

Is there a simple function that allows for a character by character examination of a string variable, or am I going to have to build a complex Regex and Loop Parse hybrid?

var := "Test String with delimiters such as commas, and semicolons; make this work."
Task: What is the 20th character in %var%?
Answer: Should be 'l', but what function finds that?

Task: What is the 43rd character in %var%?
Answer: Should be ',', but again, what function finds that?

Task: Is the 5th character in %var% a letter, a number, or a special character?
Answer: Special Character %Space%

I was hoping for something like this:

Code: Select all

var := "Test String with delimiters such as commas, and semicolons; make this work."
Answer = GetChar(pos,var) ; returns the character as the specific position in var

Example:

Code: Select all

var := "Test String with delimiters such as commas, and semicolons; make this work."
Loop, var.MaxIndex()
{
Msgbox, , Individual Char Output, % "Character " GetChar(%A_Index%,var) " found at position " %A_Index% ". Have a nice day."
}
Am I just being daft?
User avatar
Chunjee
Posts: 1479
Joined: 18 Apr 2014, 19:05
Contact:

Re: A function for Char by Char examination?

10 Jul 2020, 10:26

I'll give it a shot

Code: Select all

A := new biga() ; requires https://www.npmjs.com/package/biga.ahk

var := "Test String with delimiters such as commas, and semicolons; make this work."

; Task: What is the 43rd character in %var%?
msgbox, % A.slice(var).43
; => ","

; Task: What is the 20th character in %var%?
msgbox, % A.head(A.slice(var, 20, 20))
; => "l"
Here is a plain jane ahk one. Probably the simplest

Code: Select all

var := "Test String with delimiters such as commas, and semicolons; make this work."
msgbox, % StrSplit(var).5
; => " "
TXShooter
Posts: 165
Joined: 13 Dec 2017, 09:27

Re: A function for Char by Char examination?

10 Jul 2020, 10:52

Thanks, @BoBo .

Here's where my rabbit trail took me:

Code: Select all

string := "Test String with delimiters such as commas, and semicolons; make this work."
l := StrLen(string)
Loop, %l%
{
	Msgbox, , GetChar Output, % "Character " GetChar(A_Index,string) " found at position " A_Index ". Have a nice day."
}

ExitApp

GetChar(location,data)
{
	character := SubStr(data,location,1)
	return character
}
guest3456
Posts: 3465
Joined: 09 Oct 2013, 10:31

Re: A function for Char by Char examination?

10 Jul 2020, 11:24

TXShooter wrote:
10 Jul 2020, 10:04
Is there a simple function that allows for a character by character examination of a string variable, or am I going to have to build a complex Regex and Loop Parse hybrid?
my first thought was Loop, Parse :

https://www.autohotkey.com/docs/commands/LoopParse.htm

Code: Select all

var := "Test String with delimiters such as commas, and semicolons; make this work."

Loop, Parse, var
{
   if (A_Index = 5)
   {
      if A_LoopField is alpha
         MsgBox, 5th char is letter
      else if A_LoopField is number
         MsgBox, 5th char is number
      else if A_LoopField is space
         MsgBox, 5th char is space
   }
   else if (A_Index = 20)
      MsgBox, 20th char is %A_LoopField%
   else if (A_Index = 43)
      MsgBox, 43th char is %A_LoopField%
}

BoBo
Posts: 6564
Joined: 13 May 2014, 17:15

Re: A function for Char by Char examination?

10 Jul 2020, 11:27

TXShooter wrote:
10 Jul 2020, 10:52
Thanks, @BoBo .

Here's where my rabbit trail took me:
[...]
Well, what you are doing in your script is a default feature of AHK ...

Code: Select all

string := "Test String with delimiters such as commas, and semicolons; make this work."
Loop, Parse, string    ; ... character by character.
	Msgbox, , GetChar Output, % "Character " A_LoopField " found at position " A_Index ; while A_LoopField + A_Index deliver the expected values.

TXShooter
Posts: 165
Joined: 13 Dec 2017, 09:27

Re: A function for Char by Char examination?

10 Jul 2020, 11:30

Chunjee wrote:
10 Jul 2020, 11:14
GetChar(data,location) makes more sense to me, but yeah that is good too :thumbup:
Good point. Thank you.
TXShooter
Posts: 165
Joined: 13 Dec 2017, 09:27

Re: A function for Char by Char examination?

10 Jul 2020, 11:36

BoBo wrote:
10 Jul 2020, 11:27

Code: Select all

string := "Test String with delimiters such as commas, and semicolons; make this work."
Loop, Parse, string    ; ... character by character.
	Msgbox, , GetChar Output, % "Character " A_LoopField " found at position " A_Index ; while A_LoopField + A_Index deliver the expected values.

"If this parameter is blank or omitted, each character of InputVar will be treated as a separate substring."

I did not catch that Parse worked on strings without a delimiter. Very good to know. Thank you for pointing that out.
TXShooter
Posts: 165
Joined: 13 Dec 2017, 09:27

Re: A function for Char by Char examination?

10 Jul 2020, 12:58

BoBo wrote:
10 Jul 2020, 11:27
TXShooter wrote:
10 Jul 2020, 10:52
Thanks, @BoBo .

Here's where my rabbit trail took me:
[...]
Well, what you are doing in your script is a default feature of AHK ...
Will Loop, Parse work inside another Loop, Parse?

In my original script, I'm first searching for delimiters of `,%A_Space%:-;

Code: Select all

	Loop, Parse, CellOpen_Verse, `,%A_Space%:-; 
	{
		; Calculate the position of the delimiter at the end of this field.
			Position += StrLen(A_LoopField) + 1
		; Retrieve the delimiter found by the parsing loop.
			Delimiter := SubStr(CellOpen_Verse, Position, 1)
		; Output current results for test
			MsgBox, , BuildURL Step 1, % "Entry: " CellOpen_Verse "`nLoop: " A_Index "`nField: " A_LoopField "`nDelimiter: " Delimiter
		; Check A_LoopField at each Delimiter.

			if (Delimiter = " ") 	; Delimiter is a space, which could be after the first Book entry (ie "John 1"), 
			{						; 	or between Book number and Book name (ie "1 John"),
									;	or after an Entry delimiter of ";" (ie. "John 1:1-3; John 2:1")
				if (Position > 1)
					if (GetChar(A_LoopField,Position-1) is alpha) ; Book Found. Store it in %Book% array (untested)


			}
I'm wanting to evaluate a string such as, "Luke 10:38-42, 32; Genesis 1:1-20,32,35" to break it down into Books, Chapters, and Verses, so that the results will be:

Code: Select all

Book := ["Luke","Luke","Genesis","Genesis","Genesis"]
Chapter := ["10","10","1","1","1"]
Verses := ["38-42","32","1-20","32","35"]
Ultimately I'm trying to build this so that each array entry can be used to build some HTML code, one URL per %Entry%:

Code: Select all

Entry := "[LUK.10:37.42","LUK.10:31","GEN.1:1.20","GEN.1:32","GEN.1:35"]
I figure that there has to be a lot of sub-searching to get %Entry%, or even %Book%, %Chapter%, %Verse% arrays built.

So how will another instance of Loop, Parse work inside the current one?

In one 'sub-search' for the Delimiter of %Space%, I'm needing to evaluate the character before each %Space% in the 'outer' Loop, Parse. If it's an alpha, then I have found a Book Title (ie "John 1"), otherwise I need to evaluate if the space comes after a book number (ie "1 John"). And to complicate things further, I'm needing to evaluate if the space happens after a semicolon (ie. "John 1:10-11; John 2:23"), which indicates a second Book Title and that specific %Space% is garbage.

Sooo... in your opinion, which approach should I take?
BoBo
Posts: 6564
Joined: 13 May 2014, 17:15

Re: A function for Char by Char examination?

11 Jul 2020, 14:37

I'd recommend using RegEx to solve this challenge. The following (RegEx-free) code isn't exactly what you are looking for. So this is just for the records:

Code: Select all

; str	:= "Luke 10:38-42, 32"	
  str	:= "Genesis 1:1-20,32,35"

MsgBox % b	:= StrSplit(str,A_Space).1										; Luke	|	Genesis
MsgBox % c	:= StrSplit(StrSplit(str,A_Space).2, ":").1						; 10	|	1

v := StrSplit(StrSplit(str,":").2, ",")										; split comma separated verses 
Loop % v.Length()															; loop for the number of verses in string
	MsgBox % v[A_Index]														; showtime

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: a_riva, Bing [Bot], MSN [Bot], peter_ahk, Xeilous and 208 guests