So I am having a issue with Lua gsub removing apostrophes from strings if there is one apostrophe on its own or loads of them i can't seem to get it to remove any of them.
local uri_without_args = "'" --one on its own
local uri_without_args = "''''''''lol''''" --in text
local uri_without_args = "''''''''''''" --loads
--etc--etc all occurrences must go
local list = {
"%'", --apostrophe
}
for k,v in ipairs(list) do
local uri_without_args_remove_duplicates, occurrences = uri_without_args:gsub(""..v.."","")
if occurrences > 0 then
occurrences = occurrences + 1
for i=1, occurrences do
if uri_without_args_remove_duplicates=="" then
--do nothing
else
uri_without_args = uri_without_args:gsub(""..v.."","")
end
end
end
end
print(uri_without_args)
The only time you assign a new value to uri_without_args is when uri_without_args_remove_duplicates is not empty. If you either remove the if statement from around the assignment to uri_without_args, or if uri_without_args starts off as "''''''''lol''''", then it works fine.
As Egor said in the comment, you also could simply use uri_without_args_remove_duplicates as the result value.
Related
I'm trying to figure out how to randomly select multiple entries in a table.
This is what I have currently
local letters = {"w", "x", "y", "z"}
function randomletterselect()
local randomletters = {}
for i,v in pairs(letters) do
table.insert(randomletters,i)
end
local letter = letters[randomletters[math.random(#randomletters)]]
-- set multiple selected letters to the new table?
end
randomletterselect()
this code here works for selecting ONE random element(letter) from the table. essentially, when I run this, I want it to be multiple random letters selected. for example, one time it may select x,y another time it may be x,y,z.
The closest thing I found was honestly just what I had figured out, in this post Randomly select a key from a table in Lua
You can do...
randomletterselect=function()
local chars={}
for i=65,math.random(65,90) do
table.insert(chars,string.char(math.random(65,90)):lower())
end
print(table.concat(chars,','))
return chars
end
randomletterselect()
...for lowercase letters.
And this version returns a table without doubles...
randomletterselect=function()
local chars=setmetatable({},{__name='randomletters'})
for i=65,90 do
table.insert(chars,string.char(i):lower())
end
for i=1,math.random(#chars) do
table.remove(chars,math.random(#chars))
end
print(#chars,table.concat(chars,','))
return chars
end
local tbl = {'a', 'b', 'c', 'd'} -- your characters here
local MIN_NUM, MAX_NUM = 1, 2 ^ #tbl - 1
-- if the length of the table has changed, MAX_NUM gonna change too
math.randomseed(os.time())
local randomNum = math.random(MIN_NUM, MAX_NUM)
local function getRandomElements(num)
local rsl = {}
local cnt = 1
while num > 0 do
local sign = num % 2 -- to binary
-- if the num is 0b1010, sign will be 0101
num = (num - sign)/2
if sign == 1 then
local idx = #rsl + 1
-- use tbl[#tbl + 1] to expand the table (array)
rsl[idx] = tbl[cnt]
end
cnt = cnt + 1
end
return table.concat(rsl)
end
print(getRandomElements(randomNum))
I have another method to solve the problem, try.
MIN_NUM should be 1 cuz when its 0, getRandomElements will return an empty string
I am trying to modify my URL to be clean and friendly by removing more than one occurrence of specific characters
local function fix_url(str)
return str:gsub("[+/=]", {["+"] = "+", ["/"] = "/", ["="] = "="}) --Needs some regex to remove multiple occurances of characters
end
url = "///index.php????page====about&&&lol===you"
output = fix_url(url)
What I would like to achieve the output as is this :
"/index.php?page=about&lol=you"
But instead my output is this :
"///index.php????page====about&&&lol===you"
Is gsub the way i should be doing this ?
I don't see how to do this with one call to gsub. The code below does this by calling gsub once for each character:
url = "///index.php????page====about&&&lol===you"
function fix_url(s,C)
for c in C:gmatch(".") do
s=s:gsub(c.."+",c)
end
return s
end
print(fix_url(url,"+/=&?"))
Here's one possible solution (replace %p with whatever character class you like):
local
function fold(s)
local ans = ''
for s in s:gmatch '.' do
if s ~= ans:sub(-1) then ans = ans .. s end
end
return ans
end
local
function fix_url(s)
return s:gsub('%p+',fold) --remove multiple same characters
end
url = '///index.php????page====about&&&lol===you'
output = fix_url(url)
print(output)
I am trying to make a lua script that takes an input of numbers seperated by commas, and turns them into letters, so 1 = a ect, however I have not found a way to do this easily because the string libray outputs a = 97, so I have no clue where to go now, any help?
You can use string.byte and string.char functions:
string.char(97) == "a"
string.byte("a") == 97
If you want to start from "a" (97), then just subtract that number:
local function ord(char)
return string.byte(char)-string.byte("a")+1
end
This will return 1 for "a", 2 for "b" and so on. You can make it handle "A", "B" and others in a similar way.
If you need number-to-char, then something like this may work:
local function char(num)
return string.char(string.byte("a")+num-1)
end
Merely just account for the starting value of a-z in the ascii table.
function convert(...)
local ar = {...}
local con = {}
for i,v in pairs(ar) do
table.insert(con, ("").char(v+96))
end
return con;
end
for i,v in pairs(convert(1,2,3,4)) do
print(v)
end
Alternatively to these answers, you could store each letter in a table and simply index the table:
local letters = {'a','b','c'} --Finish
print(letters[1], letters[2], letters[3])
Define your encoding as follows:
encoding = [[abc...]]
in whatever order you want.
Then use it as follows
function char(i)
return encoding:sub(i,i)
end
If the list of numbers is in a table, then you may use
function decode(t)
for i=1,#t do t[i]=char(t[i]) end
return table.concat(t)
end
You can also save the decoding in a table:
char = {}
for i=1,#encoding do char[i]=encoding:sub(i,i) end
and use char[t[i]] in decode.
I have a variable message which I get from User input. For example:
!word number
word-word---word
or
!word
wordword-word
Currently I create a table and fill it with every single word/number (without digits like -)
--input table
it = {}
--put input in table
for _input in string.gmatch((message), '%w+') do
it[#it+1] = { input=_input }
end
First of all I cant get words with minus between them to my table.
Also I cant check if it[2].input is not empty. This is an example how I check the table:
--TEST START
if it[1].input == 'test' then
--do something
end
--TEST END
I've tried this without any working result.
-- %s = space character
-- %- = escaped magic character
message = "!word number word-word---word"
-- might not be the most ideal method to fil an array up...
it = {(function() local t = {}; for _input in string.gmatch(message,"[^%s%-]+") do t[#t+1] = {input = _input} end return unpack(t) end)()}
print(t[2].input) --> number
--
--
it = {}
for _input in string.gmatch(message,"[^%s%-]+") do
it[#it+1] = {input = _input}
end
-- now checking value should work fine
if (it[2] and it[2].input == "number") then -- checking that it[2] is set as something and then comparing input
print("t[2].input = \"number\"");
end
I have 2 functions in Lua which create a dictionary table and allow to check if a word exists:
local dictTable = {}
local dictTableSize = 0
function buildDictionary()
local path = system.pathForFile("wordlist.txt")
local file = io.open( path, "r")
if file then
for line in file:lines() do
dictTable[line] = true
dictTableSize = dictTableSize + 1
end
io.close(file)
end
end
function checkWord(word)
if dictTable[word] then
return(true)
else
return(false)
end
end
Now I want to be able to generate a couple of random words. But since the words are the keys, how can I pick some, given the dictTableSize.
Thanks
Just add a numerical index for each word to the dictionary while loading it:
function buildDictionary()
local path = system.pathForFile("wordlist.txt")
local file = io.open( path, "r")
if file then
local index = 1
for line in file:lines() do
dictTable[line] = true
dictTable[index] = line
index = index + 1
end
io.close(file)
end
end
Now you can get a random word like this:
function randomWord()
return dictTable[math.random(1,#dictTable)]
end
Side note: nil evaluates to false in Lua conditionals, so you could write checkWord like this:
function checkWord(word)
return dictTable[word]
end
Another side note, you'll get less polution of the global namespace if you wrap the dictionary functionality into an object:
local dictionary = { words = {} }
function dictionary:load()
local path = system.pathForFile('wordlist.txt')
local file = io.open( path, 'r')
if file then
local index = 1
for line in file:lines() do
self.words[line] = true
self.words[index] = line
index = index + 1
end
io.close(file)
end
end
function dictionary:checkWord(word)
return self.words[word]
end
function dictionary:randomWord()
return self.words[math.random(1,#self.words)]
end
Then you can say:
dictionary:load()
dictionary:checkWord('foobar')
dictionary:randomWord()
Probably two ways: you can keep the array with words and just do words[math.random(#words)] when you need to pick a random word (just make sure that the second one is different from the first).
The other way is to use next the number of times you need:
function findNth(t, n)
local val = next(t)
for i = 2, n do val = next(t, val) end
return val
end
This will return b for findNth({a = true, b = true, c = true}, 3) (the order is undefined).
You can avoid repetitive scanning by memoizing the results (at this point you will be better off using the first way).
this is a trade off that you have for using the word table the way you are. i would invert the word table once you load it, so that you can get references to words by index as well if you have to. something like this:
-- mimic your dictionary structure
local t = {
["asdf"] = true, ["wer"] = true, ["iweir"] = true, ["erer"] = true
}
-- function to invert your word table
function invert(tbl)
local t = {}
for k,_ in pairs(tbl) do
table.insert(t, k)
end
return t
end
-- now the code to grab random words
local idx1, idx2 = math.random(dictTableSize), math.random(dictTableSize)
local new_t = invert(t)
local word1, word2 = new_t[idx1], new_t[idx2]
-- word1 and word2 now have random words from your 'dictTable'