How to concatenate a number and a textstring in auto hotkey - autohotkey

I know a simular question has been asked before here:
How to concatenate a number and a string in auto hotkey
But this question only takes numbers into account. My problem is a bit different. For example:
myStr = A literal string
myInt = 5
Now I wish to concatenate both into a new string: 5A literal string
This is what I've tried so far:
newStr = %myInt%%myStr% ;Result: Error illegal character found
newStr = % myInt myStr ;Result: Some number
convertString = (%myInt% . String)
newStr = %convertString%%myStr% ;Result: Error illegal character found
It seems like no matter what I try, AHK just can't handle concatenating an integer with a textstring. Has anyone experience with this and know a way to get it working?
EDIT
I should add that I can't solve the issue by doing myInt = "5" as I need to operate on the integer in a loop with myInt++. Also a second question that I haven't figured out yet is: How to add unicode to the string? I thought it was U+0003, but that doesn't seem to work.
EDIT 2
It seems someone else isn't getting the same results. I've updated AHK but the problems remains. So I'll be including my exact code here, perhaps I'm doing something wrong?
global OriText ;Contains textstring
global NewText ;Empty
global ColorNumber
ColorNumber = 2
convert_text(){
StringSplit, char_array, OriText
Loop, %char_array0%
{
thisChar := char_array%a_index%
NewText += % ColorNumber thisChar
MsgBox, %NewText%
ColorNumber++
if (ColorNumber = 13){
ColorNumber = 2
}
}
GuiControl,, NewText, %NewText%
ColorNumber = 2
}
Short explanation: I'm building a little tool that will automaticly colorize text in irc adding a different color to each character. Therefor splitting the string into an array and trying to add:
U:0003ColorNumberCharacter
Where U:0003 should be the unicode for the character used in mIRC with (Ctrl+K).

You used
NewText += % ColorNumber thisChar
+ is used for adding up numbers. But the operator for concatenating strings is . in AutoHotkey. Note that this all varies from language to language. So it should be:
NewText .= ColorNumber . thisChar
which is the same as
NewText := NewText . ColorNumber . thisChar
And whenever you use the := operator, there is no need for any % in simple assignments - only when assigning in two steps, e.g., with arrays, like you did correctly with thisChar.
Another way to express the allocation above, with the plain = operator would be
NewText = %NewText%%ColorNumber%%thisChar%
which you figured out yourself already.

It turned out I was simply using the wrong operator. The correct code was:
NewText = %NewText%%ColorNumber%%thisChar%

Related

Use Autohotkey variable in text snippet

After many times of seraching i could not find an answer regarding my use case on Google or Stack Overflow.
I'm heavily using Autohotkey snippets like this for email:
:*:emailsignature::
(
Email signature text
)
But sometimes i need to temporarily add some more text inside the existing snippet.
:*:emailsignature::
(
Email signature text
%datewithtext%
Email signature text
)
::datewithtext::*** Date with text ***
So what i was wishing for is to add a variable inside the snippet as shown above. And of course I've tried the variable syntax from AHK, but got all sorts of errors.
So hopefully someone can point my in the right direction or even better show me an example code.
Thanks in advance.
On top of all the other suggestions, I would suggest to prevent you having to write "emailsignature" to trigger the text expansion. Instead, I would use e.g. "es". This short string is unique enough with the \ as the closing character to never (seldom) collide. I use this trick for many long words.
You could try this as a solution
:*:emailsignature:: ; hotstrings expect a literal string on one line,
; but can be used like hotkeys as well.
FormatTime, Date
dateWithText =
( ; the continuation section below works when assigning to a variable
Email signature text
%Date%
Email signature text
)
Return
::datewithtext::
Send % dateWithText
Return
OR, you could get kind of fancy
; auto-execute section
V_EmailSignature := "myemail#yahoo.com"
V_MomEmail := "mom#yahoo.com"
V_StreetAddress := "123 Any Street`r`nAnytown, ID, 12345"
Return ; end auto-execute section
; HOTSTRINGS
:*:emailsignature::
:*:momemail::
:*:streetaddress::
FormatTime, Date
vName := regexReplace(A_ThisHotkey, "\W")
newText := V_%vName%
dateWithText := Join("`r`n", newText, Date, newText)
Return
::datewithtext::
Send % dateWithText
Return
Join(delim, Strs*) {
newStr := ""
for _, Str in Strs {
newStr .= (newStr ? Delim : "") . Str
}
Return newStr
}
Does that help you?

Converting numbers into timestamps (inserting colons at specific places)

I'm using AutoHotkey for this as the code is the most understandable to me. So I have a document with numbers and text, for example like this
120344 text text text
234000 text text
and the desired output is
12:03:44 text text text
23:40:00 text text
I'm sure StrReplace can be used to insert the colons in, but I'm not sure how to specify the position of the colons or ask AHK to 'find' specific strings of 6 digit numbers. Before, I would have highlighted the text I want to apply StrReplace to and then press a hotkey, but I was wondering if there is a more efficient way to do this that doesn't need my interaction. Even just pointing to the relevant functions I would need to look into to do this would be helpful! Thanks so much, I'm still very new to programming.
hfontanez's answer was very helpful in figuring out that for this problem, I had to use a loop and substring function. I'm sure there are much less messy ways to write this code, but this is the final version of what worked for my purposes:
Loop, read, C:\[location of input file]
{
{ If A_LoopReadLine = ;
Continue ; this part is to ignore the blank lines in the file
}
{
one := A_LoopReadLine
x := SubStr(one, 1, 2)
y := SubStr(one, 3, 2)
z := SubStr(one, 5)
two := x . ":" . y . ":" . z
FileAppend, %two%`r`n, C:\[location of output file]
}
}
return
Assuming that the "timestamp" component is always 6 characters long and always at the beginning of the string, this solution should work just fine.
String test = "012345 test test test";
test = test.substring(0, 2) + ":" + test.substring(2, 4) + ":" + test.substring(4, test.length());
This outputs 01:23:45 test test test
Why? Because you are temporarily creating a String object that it's two characters long and then you insert the colon before taking the next pair. Lastly, you append the rest of the String and assign it to whichever String variable you want. Remember, the substring method doesn't modify the String object you are calling the method on. This method returns a "new" String object. Therefore, the variable test is unmodified until the assignment operation kicks in at the end.
Alternatively, you can use a StringBuilder and append each component like this:
StringBuilder sbuff = new StringBuilder();
sbuff.append(test.substring(0,2));
sbuff.append(":");
sbuff.append(test.substring(2,4));
sbuff.append(":");
sbuff.append(test.substring(4,test.length()));
test = sbuff.toString();
You could also use a "fancy" loop to do this, but I think for something this simple, looping is just overkill. Oh, I almost forgot, this should work with both of your test strings because after the last colon insert, the code takes the substring from index position 4 all the way to the end of the string indiscriminately.

Why doesn't a for-loop iterate without compound assignment operators

I am trying to replace every character of source string with "🥃". If I remove += from my code, the for-loop iterates only once, and I can't seem to follow the logic behind this.
However, if I use +=, the for-loop iterates. Shouldn't iterations have equalled the number of characters in stringExample? I mean my understanding was always: "For every 'item' in 'items', execute this code."
let stringExample = "Hello, Playground"
var emptyString = ""
for _ in stringExample {
emptyString = "🥃"
}
print(emptyString)
My console prints:
🥃
You are correct that emptyString = "🥃" is indeed run as many times as there are characters in stringExample. However, you misunderstood what emptyString = "🥃" actually does.
emptyString = "🥃" sets the value of emptyString to "🥃". That's what the assignment operator "=" does. It doesn't care about what was in emptyString before. After this line, emptyString will have the value "🥃". So it doesn't matter how many times you run emptyString = "🥃", at the end of the day, emptyString is still going to be "🥃".
On the other hand, += appends "🥃" to what's already in emptyString, and sets the result to emptyString.
By the way, a shorter way to do what you are trying to do is:
let beers = String(repeating: "🥃", count: stringExample.count)
add
+=
instead =
or write emptyString = emptyString + "🥃"

Remove "square brackets and characters within it" from the string-- Matlab

I have a problem removing the text and special characters from the string. For eg:
str = 'Accleration [ms^{{-}2}]';
The expected output: str_out = 'Acceleration'; I tried using the function regexprep but couldn't get the result as expected.
You can try
opens = str == '[';
closes = str == ']';
nestingcount = cumsum(opens - [0 closes(1:end-1)]);
outstr = str(nestingcount == 0);
Note that trimming trailing spaces was not part of your specification, you'll have to do that as well to get your example to work right.

Capitalizing only the first letters without changing any numbers or punctuation

I would like to modify a string that will have make the first letter capitalized and all other letters lower cased, and anything else will be unchanged.
I tried this:
function new_string=switchCase(str1)
%str1 represents the given string containing word or phrase
str1Lower=lower(str1);
spaces=str1Lower==' ';
caps1=[true spaces];
%we want the first letter and the letters after space to be capital.
strNew1=str1Lower;
strNew1(caps1)=strNew1(caps1)-32;
end
This function works nicely if there is nothing other than a letter after space. If we have anything else for example:
str1='WOW ! my ~Code~ Works !!'
Then it gives
new_string =
'Wow My ^code~ Works !'
However, it has to give (according to the requirement),
new_string =
'Wow! My ~code~ Works !'
I found a code which has similarity with this problem. However, that is ambiguous. Here I can ask question if I don't understand.
Any help will be appreciated! Thanks.
Interesting question +1.
I think the following should fulfil your requirements. I've written it as an example sub-routine and broken down each step so it is obvious what I'm doing. It should be straightforward to condense it into a function from here.
Note, there is probably also a clever way to do this with a single regular expression, but I'm not very good with regular expressions :-) I doubt a regular expression based solution will run much faster than what I've provided (but am happy to be proven wrong).
%# Your example string
Str1 ='WOW ! my ~Code~ Works !!';
%# Convert case to lower
Str1 = lower(Str1);
%# Convert to ascii
Str1 = double(Str1);
%# Find an index of all locations after spaces
I1 = logical([0, (Str1(1:end-1) == 32)]);
%# Eliminate locations that don't contain lower-case characters
I1 = logical(I1 .* ((Str1 >= 97) & (Str1 <= 122)));
%# Check manually if the first location contains a lower-case character
if Str1(1) >= 97 && Str1(1) <= 122; I1(1) = true; end;
%# Adjust all appropriate characters in ascii form
Str1(I1) = Str1(I1) - 32;
%# Convert result back to a string
Str1 = char(Str1);