Lua: delete specific characters in a string - string

I have a string that includes all the characters which should be
deleted in a given string. With a nested loop I can iterate through
both strings. But is there a shorter way?
local ignore = "'`'"
function ignoreLetters( c )
local new = ""
for cOrig in string.gmatch(c,".") do
local addChar = 1
for cIgnore in string.gmatch(ignore,".") do
if cOrig == cIgnore then
addChar = 0
break -- no other char possible
end
end
if addChar>0 then new = new..cOrig end
end
return new
end
print(ignoreLetters("'s-Hertogenbosch"))
print(ignoreLetters("'s-Hertogen`bosch"))
The string ignore can also be a table if it makes the code shorter.

You can use string.gsub to replace any occurance of a given string in a string by another string. To delete the unwanted characters, simply replace them with an empty string.
local ignore = "'`'"
function ignoreLetters( c )
return (c:gsub("["..ignore.."]+", ""))
end
print(ignoreLetters("'s-Hertogenbosch"))
print(ignoreLetters("'s-Hertogen`bosch"))
Just be aware that in case you want to ignore magic characters you'll have to escape them in your pattern.
But I guess this will give you a starting point and leave you plenty of own work to perfect.

Related

How to replace string in lua?

My question is how can I replace the character from a given string?
If someone says something in the chat, and that word is a bad word then replace it with "****".
I don't know how to approach the print section.. Because I've got the index of the badword but I don't know how to replace it from the original message.
local badwords = {
"badword",
"badword2",
}
function(msg)
local message = msg;
local lowered_msg = message:lower();
for index, val in pairs(badwords) do
if lowered_msg:match(val) then
local indexStart, indexEnd = string.find(lowered_msg, val)
print(message:gsub(indexStart, "*****", indexEnd))
end
end
end
The gsub function takes three arguments:
the string to be modified,
the pattern to be replaced,
and the replacement string,
so you need to do something like this:
message = string.gsub(message, message:sub(indexStart, indexEnd), "*****")
print(message)
This Way use a table with badwords and replacements for gsub.
local badwords = {fair='f**r', foul='f**l'}
print(('fair is foul and foul is fair'):gsub('%w+', badwords))
...if the pattern matches words.
gsub() loops over the whole string except the 4th argument is used

Lua - how to make an if condition with an string with a variable %d in the middle?

So I am trying to compare if a string match an pattern ( and I must know that after the string there is nothing else !!! ) and inside that string is a number ( I don't know which number is )
I made this function but it don't work in some cases and I think there must already be a solution!
function Match(string, pattern)
local start , final = string.find(string,pattern)
local len = string.len( string )
if len == final then return true else return false end
end
and I call it like this
if Match(item_loop_name,"!MEx CH %d+ %- "..name) == true then
--bla bla bla doing something
end
the problem my variable name sometimes have special characters like - ! % that mess with string.find
Thanks a lot
If you want to ensure your pattern is found at the end of the string you can simply anchor your pattern at the end of the string using $
local str = "I own 3 pigs and a cow"
"I own %d+ pigs" would match.
"I own %d+ pigs$" would not.
So instead of checking the string's last character's position vs the string length you can simply do something like
local stringOk = yourString:match("yourPattern$") and true or false
or
local stringOk = yourString:find("yourPattern$") and true or false
Please refer to the Lua manual!
Please understand that no further help can be given without string examples.

Groovy: remove specific characters from end of string

I have a string that might end with multiple \n (the two symbols, not a newline).
How can I remove that from the end of the string?
For example: abc\ndef\n\n should become abc\ndef
Thanks
For such a simple task a simple trim() would suffice:
assert 'abc\ndef' == 'abc\ndef\n\n\n\n'.trim()
You can do it like this:
s = "abc\ndef\n\n"
assert s.replaceAll(/\n*$/, "") == "abc\ndef"
The section between // looks for any amount of \n and the $ represents the end of the string. So, replace any amount of newlines with nothing else after them, with an empty string.

How to validate this string when we don't have the `|` operator in Lua?

I have strings of the form:
cake!apple!
apple!
cake!juice!apple!cake!
juice!cake!
In other words, these strings are composed of the three sub-strings "cake!", "apple!" and "juice!".
I need to validate these strings. The way to do this with a regular expression is thus:
/^(apple!|juice!|cake!)*$/
But Lua's patterns don't have the | operator, so it seemingly can't be done this way.
How can I validate my strings in Lua?
(I don't care about the contents of the strings: I only care about whether they conform (validate) or not.)
I know to write the code to do this but I can't think of a short way to do this. I'm looking for a short solution. I wonder if there's an elegant solution that I'm not aware of. Any ideas?
if str:gsub("%w+!", {["apple!"]="", ["juice!"]="", ["cake!"]=""}) == "" then
--do something
end
This solution uses a table as the second parameter to string.gsub. Since the patterns all match %w+, the table will validate for second time, only the real three patterns are replaced with an empty string. If after all the replacement, the string becomes empty, then the match succeeds.
Using a helper table variable can make it more clear:
local t = {["apple!"]="", ["juice!"]="", ["cake!"]=""}
if str:gsub("%w+!", t) == "" then
--do something
end
If there is a character that will never be in your string, for instance, the character "\1"(ASCII 1) is unlikely in a normal string, you can use this:
local str = "cake!juice!apple!cake!"
if str:gsub("apple!","\1"):gsub("juice!","\1"):gsub("cake!","\1"):gsub("\1","") == "" then
--do something
end
By replacing every match of the patterns to "\1", and finally replace "\1" to an empty string, the correct match would be an empty string in the end.
It has flaws(sometimes it's impossible to find a character that is never in the string), but I think it works in many situations.
The following seems to work for (the included) quick tests.
local strs = {
"cake!apple!",
"bad",
"apple!",
"apple!bad",
" apple!bad",
"cake!juice!apple!cake!",
"cake!juice! apple!cake!",
"cake!juice!badapple!cake!",
"juice!cake!",
"badjuice!cake!",
}
local legalwords = {
["cake!"] = true,
["apple!"] = true,
["juice!"] = true,
}
local function str_valid(str)
local newpos = 1
for pos, m in str:gmatch("()([^!]+!)") do
if not legalwords[m] then
return
end
newpos = pos + m:len()
end
if newpos ~= (str:len() + 1) then
return nil
end
return true
end
for _, str in ipairs(strs) do
if str_valid(str) then
print("Match: "..str)
else
print("Did not match: "..str)
end
end
Just to provide another answer, you can do this easily with lpeg's re module:
re = require 're'
local testdata =
{
"cake!apple!",
"apple!",
"cake!juice!apple!cake!",
"cake!juice!badbeef!apple!cake!",
"juice!cake!",
"badfood",
}
for _, each in ipairs(testdata) do
print(re.match(each, "('cake!' / 'apple!' / 'juice!')*") == #each + 1)
end
This outputs:
true
true
true
false
true
false
This looks almost like your regex pattern above minus the ^ $ of course since lpeg matching is always anchored.
Lua patterns are not a replacement for regular expressions, and cannot represent this sort of pattern. In this case, you just need to repeatedly make sure the front of the string matches one of your words and then pop it off, but you probably already knew that.
Something like:
local words = {cake=1,apple=2,juice=3}
local totals = {}
local matches = 0
local invalid = 0
string.gsub("cake!","(%a+)!",
function(word)
local index = words[word]
if index then
matches = matches + 1
totals[index] = totals[index] + 1
else
invalid = invalid + 1
end
end
)
if matches > 0 and invalid == 0 then
-- Do stuff
end
This will pass each word to the supplied function where you can validate each one.
I dont know if it'll help you to get by you problem. But using string.find() i could use "or". look:
str="juice!"
print(string.find(str, "cake!" or "teste"))
best regards

Duplicates In a String

I need to write a function that takes a string and returns it with duplicate characters removed in Lua. What I need help with is...
Making a hash with letters and the counts
Making each letter equal to only one, deleting more than one occurrence
Converting hash into the new string with duplicates removed
A simple function/algorithm would be appreciated!
If you only need one instance of each character then you probably don't need to keep track of the counts; you can compare the input string against the same table you use to generate the output.
local function contains(tbl, val)
for k,v in pairs(tbl) do
if v == val then return true end
end
return false
end
local function uniq(str)
local out = {}
for s in str:gmatch(".") do
if not contains(out, s) then out[#out+1] = s end
end
return table.concat(out)
end
print( uniq("the quick brown fox jumps over the lazy dog") )
-- the quickbrownfxjmpsvlazydg
This will probably be slower than the function below for short strings, but it's generally best to avoid excessive string concatenation in Lua, for the reasons outlined here. If you're sure the output string will be fairly short, you can get rid of contains() and use this:
local function uniq(str)
local out = ""
for s in str:gmatch(".") do
if not out:find(s) then out = out .. s end
end
return out
end

Resources