TTL: wait for dynamically generated string - teraterm

I'm scripting an automation in TTL.
I have a parameter that is determined by the object I'm connecting to, so I parse it into a variable named pos. This part of the code is more than fine.
Now, I'd like to wait for a textual string like
wait 'A 'pos' B'
Note that in the string I'm waiting for, the variable pos is part of the string. This syntax isn't working because, according to docs this is waiting on either A or pos or B.
e.g. if pos=3 i'd like to wait 'A 3 B' as a whole, not as alternative. I can't find in the docs the correct syntax to achieve this.

Don't put multiple strings, create a service variable and populate it,
msg = ''
strconcat msg 'A '
strconcat msg pos
strconcat msg ' B'
wait msg
see strconcat

Related

Random string picker (string names are exactly the same, except the number)

Dim rnd As New Random
Dim quote1, quote2, quote3 As String
Dim int As Integer
int = rnd.Next(1, 3)
quote1 = "never give up"
quote2 = "always believe in yourself"
quote3 = "always follow your dreams"
MessageBox.Show("quote" & int)
Hey, can somebody please tell me, how I can assign the int to the word quote, so every time it would pick a different quote?
With only 3 quotes you can do something like
Dim quoteIndex As Integer = Rnd.Next(1, 3)
Dim quote As String = ""
Select Case quoteIndex
Case 1
quote = quote1
Case 2
quote = quote2
Case 3
quote = quote3
End Select
MessageBox.Show(quote)
But in all honesty it's a quite lame solution, more akin to ninja code than to good practices. Instead, you should use an array or a list (which can be created inside this method or come from somewhere else like an overload or a modal variable):
Dim quoteList As New List(Of String)
quoteList.AddRange({"never give up", "always believe in yourself", "always follow your dreams", "something else"})
Dim quoteChoosen As Integer = Rnd.Next(0, quoteList.Count) 'this array start at zero
MessageBox.Show(quoteList(quoteChoosen)) '
If your list evolves over time (assuming that it's stored in a variable somewhere), your method won't need to be updated. Your user could add his own motivational quotes to the list without breaking your code, for an example.
As your code it written, you're showing a string value in the MessageBox. The string is being appended to, so it is dynamic and random, but it's still a string.
To get the affect I think you're looking for, you would need to use your random value as a pointer of some sort to reference a variable value. Using an array is probably the most straight-forward way to do that with this code. Instead of having 3 distinct quote strings values, you could create an array of strings...something like
quote = new string[]
where
quote[0] = "never give up"
then you could do something like MessageBox.Show(quote[int])

How to dissect and parse a string in lua?

I am trying to make command arguments in Roblox. For example, /kill playername. The problem is I don't know how to parse the playername from the string /kill playername. This code is in something like this:
game:GetService("Players").PlayerAdded:Connect(function(Player)
Player.Chatted:Connect(function(Message)
if string.sub(1, #Message) == "/kill " then
--this means the string starts with /kill and is expecting an argument.
--How can I parse this argument from the string
end
end)
end)
Edit: I want to add /setdata <Playername> <DataToChange eg. money> <Value>
Example command:
/setdata MyRobloxUsername Money 10000
I am trying to use something like this to do so
local Command, Playername, DataToChange, Value = string.match(???)
I just need to get the values from the string into variables. I can figure out how to change the data using the variables myself. Just how to get the values from the string. How can I do what I am describing?
I unaccepted the answer because I need further help. Once I get this help I will re accept it. My next request is similar, but with 3 arguments instead of 1. I need help as string:Match() is very counter intuitive to me
Use string.match:
Message=" /kill playername "
command, arg = Message:match("%s*/(.-)%s+(.*)%s*$")
If you want this to be more flexible to more commands in the future, I suggest you take both lhf's and BotOfWar's suggestions and combine them.
local function executeCommandInMessage(message)
-- do a quick regex of the message to see if it is formatted as a command
-- all we care about is the command, any arguments are optional.
local command, arguments = string.match(message, "^/(%w+)[%s]?([%w%s]+)$")
if command ~= nil then
-- we've found a command, parse the arguments into groups of non-space characters
-- then store each word in the parts array
local parts = {}
for w in arguments:gmatch("%S+") do
table.insert(parts, w)
end
-- handle each command individually
if command == "kill" then
local player = parts[1]
print(string.format("Killing %s", player))
elseif command == "setdata" then
local player = parts[1]
local value = parts[2]
local amount = parts[3]
print(string.format("Setting %s on %s to %s", value, player, amount))
-- add any further commands to the list..
-- elseif command == "" then
end
end
end
-- listen for any message submitted by players
game:GetService("Players").PlayerAdded:Connect(function(Player)
Player.Chatted:Connect(function(msg)
-- check for any commands
executeCommandInMessage(msg)
end)
end)
In the future, if you need a better regex to parse the message, I suggest you take a look at how to do Lua pattern matching. They're pretty easy to read once you know what to look at.
I suggest splitting the string with the string.split method to get the segments, then check if the first value is what you want.
game:GetService("Players").PlayerAdded:Connect(function(Player)
Player.Chatted:Connect(function(Message)
local segments = Message:split(" ")
if((#segments >= 1) and (segments[1] == "/kill")) then
-- The rest of the arguments can be accessed like this:
local args = {unpack(segments, 2)} -- Gets every argument after the first value,
-- which is the command.
end
end)
end)

How to Add a String inside of another string without erasing the rest of it

I'm having bad times trying to add a string inside of another string in a especific position. Every time I use this code, the rest of the string become blank.
double temperature = 22.1;
unsigned char pacote[16] = "#0123456789ABCDEF";
unsigned char temp_local[3];
dtostrf(temperatura, 3, 1, temp_local);
sprintf(pacote+3,"%s", temp_local);
or
sprintf(pacote+3,temp_local);
got the same printf:
#0122.1
istead of:
#0122.16789ABCDEF
Why is it erasing all the rest of the string and not just replace the next 4 positions after [3] and leaving the rest alone.
I'm using arduino but I think that's generic C question.
Thank you very much!!!
You should move the string data into the designated position (instead of copying the string, which includes a terminating '\0'):
memcpy(pacote+3, temp_local, strlen(temp_local));
if you are using C++ then use string::substr as in
new_string = old_string.substr(0,3) + "some text" + old_string.substr(3);
In pure C you first need to ensure that the destination has enough space. sprintf returns the number of characters written. Use this to ensure that destination has sufficient space. Then concatenate the two substrings with the new string as desired.

In Swift how to obtain the "invisible" escape characters in a string variable into another variable

In Swift I can create a String variable such as this:
let s = "Hello\nMy name is Jack!"
And if I use s, the output will be:
Hello
My name is Jack!
(because the \n is a linefeed)
But what if I want to programmatically obtain the raw characters in the s variable? As in if I want to actually do something like:
let sRaw = s.raw
I made the .raw up, but something like this. So that the literal value of sRaw would be:
Hello\nMy name is Jack!
and it would literally print the string, complete with literal "\n"
Thank you!
The newline is the "raw character" contained in the string.
How exactly you formed the string (in this case from a string literal with an escape sequence in source code) is not retained (it is only available in the source code, but not preserved in the resulting program). It would look exactly the same if you read it from a file, a database, the concatenation of multiple literals, a multi-line literal, a numeric escape sequence, etc.
If you want to print newline as \n you have to convert it back (by doing text replacement) -- but again, you don't know if the string was really created from such a literal.
You can do this with escaped characters such as \n:
let secondaryString = "really"
let s = "Hello\nMy name is \(secondaryString) Jack!"
let find = Character("\n")
let r = String(s.characters.split(find).joinWithSeparator(["\\","n"]))
print(r) // -> "Hello\nMy name is really Jack!"
However, once the string s is generated the \(secondaryString) has already been interpolated to "really" and there is no trace of it other than the replaced word. I suppose if you already know the interpolated string you could search for it and replace it with "\\(secondaryString)" to get the result you want. Otherwise it's gone.

How do I remove lines from a string begins with specific string in Lua?

How do I remove lines from a string begins with another string in Lua ? For instance i want to remove all line from string result begins with the word <Table. This is the code I've written so far:
for line in result:gmatch"<Table [^\n]*" do line = "" end
string.gmtach is used to get all occurrences of a pattern. For replacing certain pattern, you need to use string.gsub.
Another problem is your pattern <Table [^\n]* will match all line containing the word <Table, not just begins with it.
Lua pattern doesn't support beginning of line anchor, this almost works:
local str = result:gsub("\n<Table [^\n]*", "")
except that it will miss on the first line. My solution is using a second run to test the first line:
local str1 = result:gsub("\n<Table [^\n]*", "")
local str2 = str1:gsub("^<Table [^\n]*\n", "")
The LPEG library is perfect
for this kind of task.
Just write a function to create custom line strippers:
local mk_striplines
do
local lpeg = require "lpeg"
local P = lpeg.P
local Cs = lpeg.Cs
local lpegmatch = lpeg.match
local eol = P"\n\r" + P"\r\n" + P"\n" + P"\t"
local eof = P(-1)
local linerest = (1 - eol)^1 * (eol + eof) + eol
mk_striplines = function (pat)
pat = P (pat)
local matchline = pat * linerest
local striplines = Cs (((matchline / "") + linerest)^1)
return function (str)
return lpegmatch (striplines, str)
end
end
end
Note that the argument to mk_striplines() may be a string or a
pattern.
Thus the result is very flexible:
mk_striplines (P"<Table" + P"</Table>") would create a stripper
that drops lines with two different patterns.
mk_striplines (P"x" * P"y"^0) drops each line starting with an
x followed by any number of y’s -- you get the idea.
Usage example:
local linestripper = mk_striplines "foo"
local test = [[
foo lorem ipsum
bar baz
buzz
foo bar
xyzzy
]]
print (linestripper (test))
The other answers provide good solutions to actually stripping lines from a string, but don't address why your code is failing to do that.
Reformatting for clarity, you wrote:
for line in result:gmatch"<Table [^\n]*" do
line = ""
end
The first part is a reasonable way to iterate over result and extract all spans of text that begin with <Table and continue up to but not including the next newline character. The iterator returned by gmatch returns a copy of the matching text on each call, and the local variable line holds that copy for the body of the for loop.
Since the matching text is copied to line, changes made to line are not and cannot modifying the actual text stored in result.
This is due to a more fundamental property of Lua strings. All strings in Lua are immutable. Once stored, they cannot be changed. Variables holding strings are actually holding a pointer into the internal table of reference counted immutable strings, which permits only two operations: internalization of a new string, and deletion of an internalized string with no remaining references.
So any approach to editing the content of the string stored in result is going to require the creation of an entirely new string. Where string.gmatch provides an iteration over the content but cannot allow it to be changed, string.gsub provides for creation of a new string where all text matching a pattern has been replaced by something new. But even string.gsub is not changing the immutable source text; it is creating a new immutable string that is a copy of the old with substitutions made.
Using gsub could be as simple as this:
result = result:gsub("<Table [^\n]*", "")
but that will disclose other defects in the pattern itself. First, and most obviously, nothing requires that the pattern match at only the beginning of the line. Second, the pattern does not include the newline, so it will leave the line present but empty.
All of that can be refined by careful and clever use of the pattern library. But it doesn't change the fact that you are starting with XML text and are not handling it with XML aware tools. In that case, any approach based on pattern matching or even regular expressions is likely to end in tears.
result = result:gsub('%f[^\n%z]<Table [^\n]*', '')
The start of this pattern, '%f[^\n%z], is a frontier pattern which will match any transition from either a newline or zero character to another character, and for frontier patterns the pre-first character counts as a zero character. In other words, using that prefix allows the rest of the pattern to match at either the first line or any other start-of-line.
Reference: the Lua 5.3 manual, section 6.4.1 on string patterns

Resources