Parsing a sentence into first letters??

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
bjukrain
Posts: 11
Joined: 16 Apr 2020, 13:17

Parsing a sentence into first letters??

04 Aug 2020, 00:19

I've been trying to make a code that takes a sentence (or paragraph) from the clipboard like “I am getting worried,” (quotation marks included), and transform it into "I a g w," so in other words, taking the first letter of each word, but keeping all the accompanying punctuation. I've spend a good amount of time (you don't want to know how long... :crazy: ) trying to fix it, but currently I get an output of " a g w, and I have no clue how to fix it. I've tried to include as many detailed notes on my code as possible so hopefully it shouldn't be too hard to follow along.

THANK YOU IN ADVANCE!!!!! I would love and greatly appreciate anyone's help. I could very well be comparing things in my if-statements with the wrong operators or something else, but I believe the problem does have to do with the way I've set up my if-statements.

Code: Select all

^G:: ;Ctrl + G to activate it.

;Retrieving the clipboard data, and splitting it up.
ClipboardData := Clipboard
WordArray := StrSplit(ClipboardData, A_Space)

ArrayLength := WordArray.length()
Outer := 1 ;Finding the array length, and creating an iterator variable.

FinalStr := "" ;Resetting the final string for multiple uses.
While Outer < (ArrayLength + 1) {
	
	PunctArray := [ ".", "," , ":", ";", "?", "!", """" ]

	Prepunct := "" ;Makes Prepunct empty each time through the outer loop. If there is no pre-punctuation, PrePunct will not be triggered in the if-statement down where FirstLettersArray is created.
	Inner := 1
	PArrayLength := PunctArray.length() ;Starting the inner loop, and determining the length of the punctuation array.
	
	;Creating the first character for pre-punct:
	FirstCharacter := Substr(WordArray[Outer],1,1) ;Creates a new string with only the first character of each word.
	
	While (Inner < (PArrayLength + 1)) { ;Looping through each element in PunctArray.
		;Looping through PunctArray to match to FirstCharacter,
		;and looping through if (InStr) to see if more punct is there.
		if (FirstCharacter := PunctArray[Inner]) {
			PrePunct := PunctArray[Inner] . PrePunct . "" ;Forcing a string with the "".
	}
		if (Instr(WordArray[Outer], PunctArray[Inner], 2)) ;Searching for any other matches for punctuation, starting at the second position to exclude the first character.
			PostPunct := PunctArray[Inner] . PostPunct . ""
		
		Inner := Inner + 1 ;Looping through each punctuation.
	}
	
	
	
	if !(Prepunct="") {
	WordArray[Outer] := PrePunct . Substr(WordArray[Outer], 2,1) . PostPunct ;If there is pre-punctuation, it takes the second letter of the substring assuming there is only one pre-punctuation character (other alternatives are super unlikely so I'm not gonna code it in).
	MsgBox, prepunct
}else{
	WordArray[Outer] := Substr(WordArray[Outer],1,1) . PostPunct ;If no pre-punctuation, it just uses the first letter and then attaches the punctuation to it.
    }
	
	
	
	FinalStr := FinalStr . " " . WordArray[Outer] ;Finally, it prints the final string, appending the newest FirstLettersArray set of characters each time.
	MsgBox, %FinalStr%
	
	PrePunct := ""
	PostPunct := "" ;Clearing both of the punctuations for the next iteration.
	
	Outer := Outer + 1 ;Looping the outer while loop to loop through each word in the paragraph.
}

Clipboard := FinalStr ;Re-assigning the string to the clipboard to be copied.
return
BoBo
Posts: 6564
Joined: 13 May 2014, 17:15

Re: Parsing a sentence into first letters??

04 Aug 2020, 05:38

Code: Select all

#SingleInstance, Force

^G::
	arr := StrSplit("I am getting worried, blabla. Blubber. Really? Duh! ""C'mon""", A_Space)	; for testing just a single line.
	Loop % arr.Length()
		{	subStr := arr[A_Index]																; the following command accepts only variables
			If subStr contains ,,,.,`:,`;,?,!,`",'												; so if the array-item contains whatever specified special char 
				punct	:= SubStr(arr[A_Index],-0,1)											; ... keep that last-character-of-the-arrray-item-thang!
			letter	:= SubStr(arr[A_Index],1,1)													; like we do with the first character of it.
			line .= " " . letter . punct														; concatenate that stuff.
			punct := ""																			; yep, only for single use! Clearance.
		}
	MsgBox % ClipBoard := Trim(line)															; Ooops, we did it (again)!
	Return
HTH. Will be tricky with "-chars as those are at the beginning and the end of an array-item ... :shh:
User avatar
Chunjee
Posts: 1499
Joined: 18 Apr 2014, 19:05
Contact:

Re: Parsing a sentence into first letters??

04 Aug 2020, 07:46

I thought this would be fun to try:

Code: Select all

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

ClipboardData := Clipboard
ClipboardData := "I am getting worried,"

lettersOnlyOutput := A.join(A.map(A.words(ClipboardData), A.head), " ")
msgbox, % lettersOnlyOutput
; => "I a g w"
I put it into one line but the idea is; 1 - get all the words into an array, 2 - map the array to a new array that only has the "head" or first letter of each word, 3 - then join them back into a string separated by spaces.
User avatar
flyingDman
Posts: 2848
Joined: 29 Sep 2013, 19:01

Re: Parsing a sentence into first letters??

04 Aug 2020, 13:51

Or:

Code: Select all

var = I am getting worried, blabla. Blubber. Really? Duh! "C'mon"
for x,y in strsplit(var," ")
	lst .= substr(y,1,1) .  ((substr(y,-0) ~= "(,|\?|\!|\.|"")") ? substr(y,-0) : "") . " "
msgbox % lst
14.3 & 1.3.7
teadrinker
Posts: 4412
Joined: 29 Mar 2015, 09:41
Contact:

Re: Parsing a sentence into first letters??

04 Aug 2020, 14:25

Code: Select all

text = “I am getting worried,”
MsgBox, % RegExReplace(text, "s).*?(\b.|[“”""\.,!\?:]+)|.*", "$1")
Last edited by teadrinker on 04 Aug 2020, 17:52, edited 1 time in total.
A_AhkUser
Posts: 1147
Joined: 06 Mar 2017, 16:18
Location: France
Contact:

Re: Parsing a sentence into first letters??

04 Aug 2020, 16:56

Hi bjukrain,

I would define and compute these following:

Code: Select all

PunctArray := [ ".", "," , ":", ";", "?", "!", """" ]
PArrayLength := PunctArray.length()
outside any kind of loop or subroutine as they have nothing 'loopy'.

Also, be careful not to confuse = and :=:

Code: Select all

; ...
if (FirstCharacter := PunctArray[Inner]) {
; ...
Correct my if I'm wrong, but I'm pretty sure you meant:

Code: Select all

; ...
if (FirstCharacter = PunctArray[Inner]) {
; ...


Code: Select all

punctChars := ",,,?,!,;,:,.," . Chr(34)

^g::
output := ""
for index, word in StrSplit(Clipboard, A_Space) {
	buffer := 1, offset := 0, suffix := ""
	if word contains %punctChars%
	{
		len := StrLen(word)
		Loop % len {
			prefix := Substr(word, buffer, 1)
			if prefix not in %punctChars%
				break
			++buffer
		}
		Loop % len-buffer {
			substr := Substr(word, offset, 1)
			if substr not in %punctChars%
				break
			suffix := substr . suffix
			--offset
		}
	}
	output .= Substr(word, 1, buffer) . suffix . A_Space
}
MsgBox % output
return
hope this helps

A_AhkUser
my scripts
bjukrain
Posts: 11
Joined: 16 Apr 2020, 13:17

Re: Parsing a sentence into first letters??

05 Aug 2020, 11:30

Wow. Absolutely blown away by your responses to this! :crazy: Thank you to all posters, I definitely learned something about simplicity in code here.
bjukrain
Posts: 11
Joined: 16 Apr 2020, 13:17

Re: Parsing a sentence into first letters??

05 Aug 2020, 12:36

Ok, so I still need your guys' help. I could just use one of your programs and it would work probably better than my own program would, but I really feel the need to get my own program working properly and learn that way. For my current code, I have no clue why the " if (PunctArray[Inner] = FirstCharacter) " part is never triggered. I went into debugging mode and it looks like PunctArray[Inner] and FirstCharacter are exactly the same except for font when inner has a value of = 7 (Corresponding to " in PunctArray), but yet the code within the if-statement is never executed. I think this is the only problem I have at this point, I've cleaned up some stuff from my last version, but this is where it makes or breaks the program. Is there something wrong with the way I've set it up? Does the font of the text I copy it from matter? I have no clue at this point. Again, I know you guys blew it out of the water helping me the first time around, so I have no doubts you'll be just as awesome this time :dance:

Code: Select all

^G:: ;Ctrl + G to activate it.

;Retrieving the clipboard data, and splitting it up.
ClipboardData := Clipboard
WordArray := StrSplit(ClipboardData, A_Space)
ArrayLength := WordArray.length()
Outer := 1 ;Finding the array length, and creating an iterator variable.

FinalStr := "" ;Resetting the final string for multiple uses of Ctrl + G.

 ;Determining the length of the punctuation array.
PunctArray := [ ".", "," , ":", ";", "?", "!", """" ]
PArrayLength := PunctArray.length()  

While Outer < (ArrayLength + 1) {
	
	Inner := 1 ;Resetting the inner while loop variable to one for the next word.
	
	
	;Creating the first character for pre-punct:
	FirstCharacter := Substr(WordArray[Outer],1,1) ;Creates a new string with only the first character of each word.
	While (Inner < (PArrayLength + 1)) { ;Looping through each element in PunctArray.
		;Looping through PunctArray to match to FirstCharacter,
		;and looping through if (InStr) to see if more punct is there.
		
		if (PunctArray[Inner] = FirstCharacter) {
			PrePunct := PunctArray[Inner] . PrePunct . "" ;Forcing a string with the "".
			
	}
		if (Instr(WordArray[Outer], PunctArray[Inner],, 2)) { ;Searching for any other matches for punctuation, starting at the second position to exclude the first character.
			PostPunct := PostPunct . PunctArray[Inner] . ""
		}
		Inner := Inner + 1 ;Looping through each punctuation.
	}
	
	
	
	if (Prepunct != "") {
	WordArray[Outer] := PrePunct . Substr(WordArray[Outer], 2,1) . PostPunct ;If there is pre-punctuation, it takes the second letter of the substring assuming there is only one pre-punctuation character (other alternatives are super unlikely so I'm not gonna code it in).
	MsgBox, prepunct
}else{
	WordArray[Outer] := Substr(WordArray[Outer],1,1) . PostPunct ;If no pre-punctuation, it just uses the first letter and then attaches the punctuation to it.
    }
	
	
	
	FinalStr := FinalStr . " " . WordArray[Outer] ;Finally, it prints the final string, appending the newest FirstLettersArray set of characters each time.
	MsgBox, %FinalStr%
	
	PrePunct := ""
	PostPunct := "" ;Clearing both of the punctuations for the next iteration.
	
	Outer := Outer + 1 ;Looping the outer while loop to loop through each word in the paragraph.
}

;Clipboard := FinalStr ;Re-assigning the string to the clipboard to be copied.
return

MsgBox, %FinalStr%



^Q:: ;Ctrl + Q to exit the program at any point.
ExitApp
return

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: Bing [Bot] and 405 guests