So if I have the variable name. How can I check if it matches a pattern?
For instance, I would like to check if the variable name equals a pattern like text_text. So words at the beginning then underscore then words. With no numbers.
I really have no idea where to even start with this.
local pattern = something
if name == pattern then
UPDATE** I have tried the following, still nothing is working.
local pattern = "a%%sa%"
if string.match (name, pattern) then
return 1
else
return 0
end
Also tried this way
local pattern = "a%_a%"
if string.match (name, pattern) then
return 1
else
return 0
end
Can I please get some help
A pattern that matches any combination of small letters linked with an underscore would be:
"%l+_%l+"
%l specifies any lower case letter,
followed by a + which specifies the number of the symbol it follows.
So %l+ means "at least one lower case letter"
_ is simply an underscore.
So the pattern "%l+_%l+" means "at least one lower case letter followed by one underscore followed by at least one lower case letter
Please refer to https://www.lua.org/pil/20.2.html and/or https://www.lua.org/manual/5.3/manual.html#6.4.1 for all the possible bricks you can construct patterns of.
You can use those patterns in the functions provided by the string standard library. string.find, string.gsub and so on.
If you want to use that stuff more excessively checkout LPeg for example.
Try this:
function match(string)
local string = string:match('^(%a+_%a+)$')
if string then
return true
else
return false
end
end
local string = match('hi I'm webrom')
print(string)
output = false
local string = match('14545_15456')
print(string)
output = false
local string = match('hello_world')
print(string)
output = true
local string = match('HELLO_WORLD')
print(string)
output = true
The pattern %a match any letter.
in string patterns in lua,
anything between parantheses will be returned
also you do % with a special caracter afterwards like a for letters, to match ONE letter
adding + after %a would make you detect THE MOST possible letters , in the pattern before you get to the next character / set of characters
for example :
s = "Hello Julia my love ! Here's a hug!"
lovername,gift = string.match(s,"(%a+) my love ! Here's a (%a+)")
print(lovername.." was given a "..gift)
In your example, you can do this :
var = "hello_world"
if (string.match(var, "%a+_%a+")) then -- In this example, _ will be normal
print("Valid variable name !")
else
print("Invalid variable name")
end
Related
I'm trying to match and return a string between two (or one if there's no closing character, then until the string's end) character.
local id = "+#a-#s,#n";
local addOperator = string.match(id, "^[+](.+)(?[-])"); -- should return "#a"
if (addOperator) then
-- ...
end
local removeOperator = string.match(id, "^[-](.+)(?[+])"); -- should return "#s,#n"
if (removeOperator) then
-- ...
end
-- Or without the excluding operator "-"
local id = "+#a";
local addOperator = string.match(id, "^[+](.+)(?[-])"); -- should return "#a", with my pattern it returns a nil.
if (addOperator) then
-- ...
end
? should come after the char you are matching 0 to 1 of.
You also can not use .+ followed by any char ? and expect the ? to restrict the results of the .+
I suggest using an a set that excludes -. Additionally you use [+] but should be using %+, % is how you escape a special character in a pattern. Using [+] to escape is not necessarily wrong functionally it just comes off as odd or non-idiomatic in Lua.
local id = "+#a-#s,#n"
print(string.match(id, "^%+([^-]+)"))
print(string.match(id, "%-(.+)"))
id = "+#a"
print(string.match(id, "^%+([^-]+)"))
This is a good resource for understanding Lua patters: Understanding Lua Patterns
I need to encapsulate in some way pattern in lua pattern matching to find whole sequence of this pattern in string. What do I mean by that.
For example we have string like that:
"word1,word2,word3,,word4,word5,word6, word7,"
I need to match first sequence of words followed by coma (word1,word2,word3,)
In python I would use this pattern "(\w+,)+", but similar pattern in lua (like (%w+,)+), will return just nil, because brackets in lua patterns means completely different thing.
I hope now you see my problem.
Is there a way to do repeating patterns in lua?
Your example wasn't too clear in terms of what should happen to the word4,word5,word6 and word7,
This would give you any seqence of comma separated words without white space or empty positions.
local text = "word1,word2,word3,,word4,word5,word6, word7,"
-- replace any comma followed by any white space or comma
--- by a comma and a single white space
text = text:gsub(",[%s,]+", ", ")
-- then match any sequence of >=1 non-whitespace characters
for sequence in text:gmatch("%S+,") do
print(sequence)
end
Prints
word1,word2,word3,
word4,word5,word6,
word7,
You could do this easily using LPeg if that's available to you:
local lpeg = require "lpeg"
local str = "word1,word2,word3,,word4,word5,word6, word7,"
local word = (lpeg.R"az"+lpeg.R"AZ"+lpeg.R"09") ^ 1
local sequence = lpeg.C((word * ",") ^1)
print(sequence:match(str))
Im trying to find out how to check in lua if a string variable has any letters in it, or numbers, like so:
myAwesomeVar = "hi there crazicrafter1"
if myAwesomeVar(has letters and numbers) then
print("It has letters and numbers!")
elseif myAwesomeVar(has letters and not numbers) then
print("It has letters!, but no numbers...")
elseif myAwesomeVar(has not letters and not numbers) then
print("It doesnt have letters or numbers...")
elseif myAwesomeVar(has not letters and numbers) then
print("It doesnt have letters, but it has numbers!")
end
I know some arguments of this are incorrect, but this is the kind of thing im aiming for my code to output:
It has letters and numbers!
As Egor suggested you would write a functions that check if a string contains any digit or any letter...
Lua provides string patterns for convenient string analysis.
function containsDigit(str)
return string.find(str, "%d") and true or false
end
I bet you can do the same for letters. Refer to Lua 5.3 Reference Manual 6.4.1: String patterns
The you can do something like
local myString = "hello123"
if containsDigit(myString) and containsDigit(myString) then
print("contains both")
end
So I'm writing a Lua script and I tested it but I got an error that I don't know how to fix:
.\search.lua:10: malformed pattern (missing ']')
Below is my code. If you know what I did wrong, it would be very helpful if you could tell me.
weird = "--[[".."\n"
function readAll(file)
local c = io.open(file, "rb")
local j = c:read("*all")
c:close()
return(j)
end
function blockActive()
local fc = readAll("functions.lua")
if string.find(fc,weird) ~= nil then
require("blockDeactivated")
return("false")
else
return("true")
end
end
print(blockActive())
Edit: first comment had the answer. I changed
weird = "--[[".."\n" to weird = "%-%-%[%[".."\r" The \n to \r change was because it was actually supposed to be that way in the first place.
This errors because string.find uses Lua Patterns.
Most non-alpha-numeric characters, such as "[", ".", "-" etc. convey special meaning.
string.find(fc,weird), or better, fc:find(weird) is trying to parse these special characters, and erroring.
You can use these patterns to cancel out your other patterns, however.
weird = ("--[["):gsub("%W","%%%0") .. "\r?\n"
This is a little daunting, but it will hopefully make sense.
the ("--[[") is the orignal first part of your weird string, working as expected.
:gsub() is a function that replaces a pattern with another one. Once again, see Patterns.
"%W" is a pattern that matches every string that isn't a letter, a number, or an underscore.
%%%0 replaces everything that matches with itself (%0 is a string that represents everything in this match), following a %, which is escaped.
So this means that [[ will be turned into %[%[, which is how find, and similar patterns 'escape' special characters.
The reason \n is now \r?\n refers back to these patterns. This matches it if it ends with a \n, like it did before. However, if this is running on windows, a newline might look like \r\n. (You can read up on this HERE). A ? following a character, \r in this case, means it can optionally match it. So this matches both --[[\n and --[[\r\n, supporting both windows and linux.
Now, when you run your fc:find(weird), it's running fc:find("%-%-%[%[\r?\n"), which should be exactly what you want.
Hope this has helped!
Finished code if you're a bit lazy
weird = ("--[["):gsub("%W","%%%0") .. "\r?\n" // Escape "--[[", add a newline. Used in our find.
// readAll(file)
// Takes a string as input representing a filename, returns the entire contents as a string.
function readAll(file)
local c = io.open(file, "rb") // Open the file specified by the argument. Read-only, binary (Doesn't autoformat things like \r\n)
local j = c:read("*all") // Dump the contents of the file into a string.
c:close() // Close the file, free up memory.
return j // Return the contents of the string.
end
// blockActive()
// returns whether or not the weird string was matched in 'functions.lua', executes 'blockDeactivated.lua' if it wasn't.
function blockActive()
local fc = readAll("functions.lua") // Dump the contents of 'functions.lua' into a string.
if fc:find(weird) then // If it functions.lua has the block-er.
require("blockDeactivated") // Require (Thus, execute, consider loadfile instead) 'blockDeactived.lua'
return false // Return false.
else
return true // Return true.
end
end
print(blockActive()) // Test? the blockActve code.
In my application I've got a procedure which should check if an input is valid or not. You can set up a regex for this input.
But in my case it returns false instead of true. And I can't find the problem.
My code looks like this:
gaps.each_index do | i |
if gaps[i].first.starts_with? "~"
# regular expression
begin
regex = gaps[i].first[1..-1]
# a pipe is used to seperate the regex from the solution-string
if regex.include? "|"
puts "REGEX FOUND ------------------------------------------"
regex = regex.split("|")[0..-2].join("|")
end
reg = Regexp.new(regex, true)
unless reg.match(data[i])
puts "REGEX WRONGGGG -------------------"
#wrong_indexes << i
end
rescue
end
else
# normal string
if data[i].nil? || data[i].strip != gaps[i].first.strip
#wrong_indexes << i
end
end
An example would be:
[[~berlin|berlin]]
The left one before the pipe is the regex and the right one next to the pipe is the correct solution.
This easy input should return true, but it doesn't.
Does anyone see the problem?
Thank you all
EDIT
Somewhere in this lines must be the problem:
if regex.include? "|"
puts "REGEX FOUND ------------------------------------------"
regex = regex.split("|")[0..-2].join("|")
end
reg = Regexp.new(regex, true)
unless reg.match(data[i])
Update: Result without ~
The whole point is that you are initializing regex using the Regexp constructor
Constructs a new regular expression from pattern, which can be either a String or a Regexp (in which case that regexp’s options are propagated, and new options may not be specified (a change as of Ruby 1.8).
However, when you pass the regex (obtained with regex.split("|")[0..-2].join("|")) to the constructor, it is a string, and reg = Regexp.new(regex, true) is getting ~berlin (or /berlin/i) as a literal string pattern. Thus, it actually is searching for something you do not expect.
See, regex= "[[/berlin/i|berlin]]" only finds a *literal /berlin/i text (see demo).
Also, you need to get the pattern from the [[...]], so strip these brackets with regex = regex.gsub(/\A\[+|\]+\z/, '').split("|")[0..-2].join("|").
Note you do not need to specify the case insensitive options, since you already pass true as the second parameter to Regexp.new, it is already case-insensitive.
If you are performing whole word lookup, add word boundaries: regex= "[[\\bberlin\\b|berlin]]" (see demo).