I have something like
str = "What a wonderful string //011// this is"
I have to replace the //011// with something like convertToRoman(011) and then get
str = "What a wonderful string XI this is"
However, the conversion into roman numbers is no problem here.
It is also possible that the string str didn't has a //...//. In this case it should simply return the same string.
function convertSTR(str)
if not string.find(str,"//") then
return str
else
replace //...// with convertToRoman(...)
end
return str
end
I know that I can use string.find to get the complete \\...\\ sequence. Is there an easier solution with pattern matching or something similiar?
string.gsub accepts a function as a replacement. So, this should work
new = str:gsub("//(.-)//", convertToRoman)
I like LPEG, therefore here is a solution with LPEG:
local lpeg = require"lpeg"
local C, Ct, P, R = lpeg.C, lpeg.Ct, lpeg.P, lpeg.R
local convert = function(x)
return "ROMAN"
end
local slashed = P"//" * (R("09")^1 / convert) * P"//"
local other = C((1 - slashed)^0)
local grammar = Ct(other * (slashed * other)^0)
print(table.concat(grammar:match("What a wonderful string //011// this is"),""))
Related
local httpService = game :GetService("HttpService")
local laber = script.Parent.SurfaceGui.TextLabel
local URL = "https://api.coingecko.com/api/v3/coins/markets?vs_currency=usd&order=market_cap_desc&per_page=100&page=1&sparkline=false"
local Data = httpService:GetAsync(URL)
local randomJokes = httpService:JSONDecode(Data)
nil.Text = randomJokes.value
Literals can't be used as "prefix expressions" to prefix .name, [exp] for assignments.
The workaround is to wrap literals in parentheses (for example: ("str"):rep(42)).
In your case, you can syntactically fix your code by wrapping nil in parentheses:
(nil).Text = randomJokes.value
which most likely is nonsense semantically, unless someone did
debug.setmetatable(nil, {__newindex = function(_, key, value) ... end})
What did you intend to achieve?
--encode
function strToBytes(str)
local bytes = { str:byte(1, -1)
for i = 1, #bytes do
bytes[i] = bytes[i] + 100
end
return table.concat(bytes, ',')
end
--decode
function bytesToStr(str)
local function gsub(c)return string.char(c - 100) end
return str:gsub('(%d+),?', gsub) end
implemented :
str = "hello world"
strbyte = strToBytes(str)
bytestr = bytesToStr(strbyte)
print(strbyte)
Output :
204,201,208,208,211,132,219,211,214,208,200
print(bytestr)
Output :
"Hello world"
Hi, I need improving my code above. Actually encode and decode functions is work fine, but I need a little bit change.
I want to make encode functions similar like code above, but, the results is table like below :
{204,201,208,208,211,132,219,211,214,208,200}
Then, same as like my first decode functions, all bytes inside the table should be back to "hello world".
I hope my purpose and explanation above is easy to understand. Thanks in advance for any help and suggestions.
Update explanation :
It is a little bit complicated to explain what is my purposes. But I will try to explain as good as I can.
I am trying to make scripts encoder. Encode functions is in encoder scripts side, and decode function is in encoded scripts side. So I must write concatenate decode function before encoded string.
To clearly my explanation, encoder scripts will load undecode source code.
file = io.open(path, "r")
local data = file:read("*l")
The problem is, table cant concatenate with string.
local data = encode(str)--the result is byte array
local data = "decode("..data..")"
file:write(data)
file:close()
local data = string.dump(load(data),true,true)
My first purpose is to hide some important string, because string.dump result is not hide all string.
My second purpose is, to make an obsfucated code using byteArray.
Any solution or suggestion?
SOLVED
function strToBytes(str)
local byteArray= { str:byte(1, -1) }
for i = 1, #byteArray do
byteArray[i] = byteArray[i] + 100
encoded = '{' ..table.concat(byteArray, ',') .. '}'
end
return "load(string.dump(load(bytesToStr("..encoded.."))))()\n"
end
Thank you so much... 👍
Your code was very close to what you were looking for.
--encode
function strToBytes(str)
local byteArray= { str:byte(1, -1) }
for i = 1, #byteArray do
byteArray[i] = byteArray[i] + 100
end
return '{' .. table.concat(byteArray, ',') .. '}'
end
For the encode I removed the table.concat and now just return the byteArray
--decode
function bytesToStr(byteArray)
local output = "" --initialize output variable
for _,b in ipairs(byteArray) do --use ipairs to preserve order
output = output .. string.char(b - 100) --convert each byte to a char and add to output
end
return output
end
For the decode I use a for loop with ipairs to iterate over each byte and concatenate the values into an output variable.
-- test
str = "hello world!"
strbyte = strToBytes(str)
bytestr = 'return bytesToStr(' .. strbyte .. ')'
strBack = string.dump(load(bytestr),true,true)
print(strbyte)
print(bytestr)
print(load(strBack)())
Test output:
{204,201,208,208,211,132,219,211,214,208,200,133}
return bytesToStr({204,201,208,208,211,132,219,211,214,208,200,133})
hello world!
I am writing a generic Log() function in lua which utilizes lua print function:
Log (variable, 'String: %s ', str, 'Word: %d', w)
Currently I'm using below approach:
print(string.format (variable, 'String: %s ', str, 'Word: %d', w))
I tried something like:
Log = function(...) begin
return print(string.format(...))
end
But it doesn't work, Is this correct approach? Or Is there any better more generic way to get this done?
If you just want to print a sequence of values, you can do that with print:
print(variable, 'String: %s ', str, 'Word: %d', w)
What you seem to want is something more complicated. Your algorithm seems to be:
For each argument:
If the argument is not a string, then convert it to a string and print it.
If the argument is a string, figure out how many % patterns it has (let us call this number k). Pass string.format the current argument string and the following k parameters, printing the resulting string. Advance k parameters.
That's a much more complicated algorithm than can be done in a one-line system.
Using Lua 5.3, here's what such a function would look like (note: barely tested code):
function Log(...)
local values = {}
local params = table.pack(...)
local curr_ix = 1
while (curr_ix <= params.n) do
local value = params[curr_ix]
if(type(value) == "string") then
--Count the number of `%` characters, *except* for
--sequential `%%`.
local num_formats = 0
for _ in value:gmatch("%%[^%%]") do
num_formats = num_formats + 1
end
value = string.format(table.unpack(params, curr_ix, num_formats + curr_ix))
curr_ix = curr_ix + num_formats
end
values[#values + 1] = value
curr_ix = curr_ix + 1
end
print(table.unpack(values))
end
I don't think your current approach works, because the first argument of string.format expects the format specifier, not the rest of the arguments.
Anyway, this is the way to combine formatting and printing together:
Log = function(...)
return print(string.format(...))
end
And call it like this:
Log("String: %s Number: %d", 'hello' , 42)
Also, it might be better to make the format specifier argument more explicit, and use io.write instead of print to get more control over printing:
function Log(fmt, ...)
return io.write(string.format(fmt, ...))
end
I have a lua string in Chinese, such as
str = '这是一个中文字符串' -- in English: 'this is a Chinese string'
Now I would like to iterate the string above, to get the following result:
str[1] = '这'
str[2] = '是'
str[3] = '一'
str[4] = '个'
str[5] = '中'
str[6] = '文'
str[7] = '字'
str[8] = '符'
str[9] = '串'
and also output 9 for the length of the string.
Any ideas?
Something like this should work if you are using utf8 module from Lua 5.3 or luautf8, which works with LuaJIT:
local str = '这是一个中文字符串'
local tbl = {}
for p, c in utf8.codes(str) do
table.insert(tbl, utf8.char(c))
end
print(#tbl) -- prints 9
I haven't used non-english characters in lua before and my emulator just puts them in as '?' but something along the lines of this might work:
convert = function ( str )
local temp = {}
for c in str:gmatch('.') do
table.insert(temp, c)
end
return temp
end
This is a simple function that utilizes string.gmatch() to separate the string into individual characters and save them into a table. It would be used like this:
t = convert('abcd')
Which would make 't' a table containing a, b, c and d.
t[1] = a
t[2] = b
...
I am not sure if this will work for the Chinese characters but it is worth a shot.
I've googled and I'm just not getting it. Seems like such a simple function, but of course Lua doesn't have it.
In Python I would do
string = "cat,dog"
one, two = string.split(",")
and then I would have two variables, one = cat. two = dog
How do I do this in Lua!?
Try this
str = 'cat,dog'
for word in string.gmatch(str, '([^,]+)') do
print(word)
end
'[^,]' means "everything but the comma, the + sign means "one or more characters". The parenthesis create a capture (not really needed in this case).
If you can use libraries, the answer is (as often in Lua) to use Penlight.
If Penlight is too heavy for you and you just want to split a string with a single comma like in your example, you can do something like this:
string = "cat,dog"
one, two = string:match("([^,]+),([^,]+)")
Add this split function on the top of your page:
function string:split( inSplitPattern, outResults )
if not outResults then
outResults = { }
end
local theStart = 1
local theSplitStart, theSplitEnd = string.find( self, inSplitPattern, theStart )
while theSplitStart do
table.insert( outResults, string.sub( self, theStart, theSplitStart-1 ) )
theStart = theSplitEnd + 1
theSplitStart, theSplitEnd = string.find( self, inSplitPattern, theStart )
end
table.insert( outResults, string.sub( self, theStart ) )
return outResults
end
Then do as follows:
local myString = "Flintstone, Fred, 101 Rockledge, Bedrock, 98775, 555-555-1212"
local myTable = myString:split(", ")
for i = 1, #myTable do
print( myTable[i] ) -- This will give your needed output
end
For more information, visit : Tutorial: Lua String Magic
Keep Coding...............:)
-- like C strtok, splits on one more delimiter characters (finds every string not containing any of the delimiters)
function split(source, delimiters)
local elements = {}
local pattern = '([^'..delimiters..']+)'
string.gsub(source, pattern, function(value) elements[#elements + 1] = value; end);
return elements
end
-- example: var elements = split("bye# bye, miss$ american# pie", ",#$# ")
-- returns "bye" "bye" "miss" "american" "pie"
To also handle optional white space you can do:
str = "cat,dog,mouse, horse"
for word in str:gmatch('[^,%s]+') do
print(word)
end
Output will be:
cat
dog
mouse
horse
This is how I do that on mediawiki:
str = "cat,dog"
local result = mw.text.split(str,"%s*,%s*")
-- result[0] will give "cat", result[1] will give "dog"
actually, if you don't care spaces, you can use:
str = "cat,dog"
local result = mw.text.split(str,",")
-- result[0] will give "cat", result[1] will give "dog"
The API used here is implemented in Scribunto MediaWiki extension. Here is the split() method reference documentation and here is the source code for that. It relies on a lot of other capabilities in Scribunto's Lua common libraries, so it will only work for you if you are actually using MediaWiki or plan to import most of the Scribunto common library.
Functions like string.split() are largely unnecessary in Lua since you can
express string operations in LPEG.
If you still need a dedicated function a convenient approach is
to define a splitter factory (mk_splitter() in below snippet)
from which you can then derive custom splitters.
local lpeg = require "lpeg"
local lpegmatch = lpeg.match
local P, C = lpeg.P, lpeg.C
local mk_splitter = function (pat)
if not pat then
return
end
pat = P (pat)
local nopat = 1 - pat
local splitter = (pat + C (nopat^1))^0
return function (str)
return lpegmatch (splitter, str)
end
end
The advantage of using LPEG is that the function accepts
both valid Lua strings and patterns as argument.
Here is how you would use it to create a function that
splits strings at the , character:
commasplitter = mk_splitter ","
print (commasplitter [[foo, bar, baz, xyzzy,]])
print (commasplitter [[a,b,c,d,e,f,g,h]])