Instr(Haystack, Needle) for multiple needles

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
alancantor
Posts: 76
Joined: 11 Jun 2019, 11:28

Instr(Haystack, Needle) for multiple needles

19 Sep 2021, 22:15

I've written an AHK script that checks whether a string (the "haystack"), which is in the clipboard, contains one of three "needles." The three needles are the period, the question mark, and the exclamation mark.

If one of the needles is in the haystack, I want to know its position. For example, if the haystack is:

Hi!

... I assign the position of the needle to 3.

The way I came up with to determine the position of the needle gets the job done, but it's klunky, as it involves replacing the needle with a nonsense "word":

Code: Select all

	If (InStr(Clipboard,".") || InStr(Clipboard,"?") || InStr(Clipboard,"!"))	; If Clipboard contains !?.
		{
		LenClip := StrLen(Clipboard)
		x := Clipboard 
		x := StrReplace(x, ".", "&*^$#@")
		x := StrReplace(x, "?", "&*^$#@")
		x := StrReplace(x, "!", "&*^$#@")
		Pos := Instr(x, "&*^$#@")
		Offset := LenClip - Pos
		}
	}
Is there a more elegant way to do this, preferably a method that doesn't involve multiple replace instructions and nonsense words?
User avatar
boiler
Posts: 16952
Joined: 21 Dec 2014, 02:44

Re: Instr(Haystack, Needle) for multiple needles

19 Sep 2021, 22:38

This works because of short-circuit boolean evaluation:

Code: Select all

Clipboard := "Hi!"
If (Pos := InStr(Clipboard,".")) || (Pos := InStr(Clipboard,"?")) || (Pos := InStr(Clipboard,"!"))	; If Clipboard contains !?.
	Offset := StrLen(Clipboard) - Pos
MsgBox, % "Pos: " Pos "`nOffset: " Offset

Or you can just use one RegEx:

Code: Select all

Clipboard := "Hi!"
If (Pos := RegExMatch(Clipboard,"[\.!?]"))	; If Clipboard contains !?.
	Offset := StrLen(Clipboard) - Pos
MsgBox, % "Pos: " Pos "`nOffset: " Offset
william_ahk
Posts: 493
Joined: 03 Dec 2018, 20:02

Re: Instr(Haystack, Needle) for multiple needles

20 Sep 2021, 00:40

Or this, without RegEx and for the sake of a cleaner syntax:

Code: Select all

Clipboard := "--->!<---"
for each, keyword in [".", "?", "!"] {
    if (Pos := InStr(Clipboard, keyword)) {
        Offset := StrLen(Clipboard) - Pos
        break
    }
}
MsgBox, % "Pos: " Pos "`nOffset: " Offset

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: downstairs, filipemb, OrangeCat and 169 guests