Is there a way to iterate over a comma-separated string, then doing something with the matches? So far I have:
for a in string.gmatch("this, is, a commaseparated, string", "(.-)[,]") do
print (a)
end
The problem is the last entry in the table is not found. In C it is possible to match against NULL to check whether you are at the end of a string. Is there something similar in Lua?
Try this:
for a in string.gmatch("this, is, a commaseparated, string", "([^,]+),?") do
print (a)
end
The regex pattern ([^,]+),? captures one or more non-comma characters that are optionally followed by a comma.
Related
If I have string as "TestDataData" I want to replace "Data" with "NewValue" so it should become "TestNewValueData", how do we achieve this ?
Note: I cant replace data directly otherwise last data will also updated..
If you are able to use a RegEx, you could use the following:
str.replace("Data.+", "NewValue")
The .+ assures at least one more letter follows after "Data".
Alternatively, you could check if the index of your needle is less than the length of the haystack minus the length of the needle.
I have various strings with forms similar to:
This is a sentence outside braces{sentence{} with some words. {This is a
sentence inside braces with some words.}{This is a second sentence
inside braces.} Maybe some more words here for another sentence.
With Lua, I want to only match specific words in the string which are outside the "{}" braces. For example, I might want to match the word "sentence" outside the braces but not the occurrences of "sentence" inside the braces. I want to only match the bolded occurrences of the word not the italicized ones.
How to do it?
EDIT: What if I want append or replace the matched words while keeping the substrings inside the braces intact?
Example: append "word" to sentence:
This is a sentenceword outside braces{sentence{} with some words. {This is a
sentence inside braces with some words.}{This is a second sentence
inside braces.} Maybe some more words here for another sentenceword.
The simplest way to do this would be to replace all the brackets with a zero length strings in a temporary variable which you can then use to search for whatever you like.
You can easily do this using Lua's pattern matching and the following simple gsub code:
local tempStr = startStr:gsub("{.-}","")
The .- is the part that makes it grab everything between the { and } and gsub then replaces it all with a blank string.
Edit: The issue with the above method, as DarkWiiPlayer has pointed out is that the first open brace mathces with the first close brace which is incorrect.
The way around that is to use balanced braces (%b) as DarkWiiPlayer has recommended in his answer, like so:
local tempStr = startStr:gsub("%b{}","")
local function weird_match(word, str)
return str:gsub("%b{}", ''):match(word)
end
Replace balanced pairs of { and } with the empty string
Find the desired pattern (word) in the resulting string
Return the matched word (or its captures, if it has any)
I'm looking for a little help on some Lua. I need some code to match this exact line:
efs.test efs.test.gpg
Here's what I have so far, which matches "efs.test":
if string.match(a.message, "%a+%a+%a+.%%a+%a+%a+%a+") then
print(a.message)
else
print ("Does not match")
end
I've also tried this, which matches:
if string.match(a.message, "efs.test") then
print(a.message)
else
print ("Does not match")
end
But when I try to add the extra text my compiler errors with "Number expected, got string" when running this code:
if string.match(a.message, "efs.test", "efs") then
print(a.message)
else
print ("Does not match")
end
Any pointers would be great!
Thanks.
if string.match(a.message, "%a+%a+%a+.%%a+%a+%a+%a+") then
Firstly, this is a wrong use of quantifiers. From PiL 20.2:
+ 1 or more repetitions
* 0 or more repetitions
- also 0 or more repetitions
? optional (0 or 1 occurrence)
In words, you try to match for unlimited %a+ after you already matched the full word with unlimited %a+
To match efs.test efs.test.gpg - we have 2 filenames I suppose, in a strict sense file names may contain only %w - alphanumeric characters (A-Za-z0-9). This would correctly match efs.test:
string.match(message, "%w+%.%w+")
Going one step further, match efs.test as filename and the following filename:
string.match(message, "%w+%.%w+ %w+%.%w+%.gpg")
While this would match both filenames, you would need to check if matched filenames are the same. We can go one step further yet:
local file, gpgfile = string.match(message, "(%w+%.%w+) (%1%.gpg)")
This pattern will return any <filename> <filename>.gpg where the filenames are equal.
With the use of capture-groups, we capture the filename: it will be returned as the first variable and further represented as %1. Then after the space char, we try to match for %1 (captured filename) followed by .gpg. Since it's also enclosed in brackets, it will become the second captured group and returned as the second variable. Done!
PS: You may want to grab ".gpg" by case-insensitive [Gg][Pp][Gg] pattern.
PPS: File names may contain spaces, dashes, UTF-8 characters etc. E.g. ext4 only forbids \0 and / characters.
string.match optional third argument is the index of the given string to start searching at. If you are looking for exactly efs.test efs.test.gpg in that order with that given spacing, why not just use:
string.match(a.message, "efs%.test efs%.test%.gpg")
If you want to match the entire line containing that substring:
string.match(a.message, ".*efs%.test efs%.test%.gpg.*")
For reference
If you are trying to match that exact line its way easier to just use:
if "efs.test efs.test.gpg" = a.message then
print(a.message)
else
print("string does not match!")
end
Of course this wouldn't find any other strings than this.
Another interpretation I see for your question is that you want to know if it has efs.test in the string, which you should be able to accomplish by doing:
if string.match(a.message, "%w+%.%w+") == "efs.test" then
...
end
Also, look into regex, it's basically the language Lua used to match strings with some exceptions.
I'm trying to find exact matches of strings in Lua including, special characters. I want the example below to return that it is an exact match, but because of the - character it returns nil
index = string.find("test-string", "test-string")
returns nil
index = string.find("test-string", "test-")
returns 1
index = string.find("test-string", "test")
also returns 1
How can I get it to do full matching?
- is a pattern operator in a Lua string pattern, so when you say test-string, you're telling find() to match the string test as few times as possible. So what happens is it looks at test-string, sees test in there, and since - isn't an actual minus sign in this case, it's really looking for teststring.
Do as Mike has said and escape it with the % character.
I found this helpful for better understanding patterns.
You can also ask for a plain substring match that ignores magic characters:
string.find("test-string", "test-string",1,true)
you need to escape special characters in the pattern with the % character.
so in this case you are looking for
local index = string.find('test-string', 'test%-string')
I have a problem with splitting string into two parts on special character.
For example:
12345#data
or
1234567#data
I have 5-7 characters in first part separated with "#" from second part, where are another data (characters,numbers, doesn't matter what)
I need to store two parts on each side of # in two variables:
x = 12345
y = data
without "#" character.
I was looking for some Lua string function like splitOn("#") or substring until character, but I haven't found that.
Use string.match and captures.
Try this:
s = "12345#data"
a,b = s:match("(.+)#(.+)")
print(a,b)
See this documentation:
First of all, although Lua does not have a split function is its standard library, it does have string.gmatch, which can be used instead of a split function in many cases. Unlike a split function, string.gmatch takes a pattern to match the non-delimiter text, instead of the delimiters themselves
It is easily achievable with the help of a negated character class with string.gmatch:
local example = "12345#data"
for i in string.gmatch(example, "[^#]+") do
print(i)
end
See IDEONE demo
The [^#]+ pattern matches one or more characters other than # (so, it "splits" a string with 1 character).