Regex in Lua¶
Lua has its own support for regular expressions (). This gives another option aside from Vim's built-in regex support.
Table of Contents¶
string.match¶
Usage¶
Using string.match is the easiest way to extract text from a string with regex.
If the regex matches, string.match returns the captures from the pattern,
otherwise it returns nil.
If the regex doesn't have any capture groups, then the whole match is returned.
nil as a match, it can be useful for if statements.
if line:match('^(#+)') then
local level = line:match('^(#+)')
local title = line:match('^#+ (.+)')
end
Get Multiple Captures from One Regex¶
Each capture group in the regex returns a string. To get multiple capture groups:
local line = vim.fn.getline('.')
local capture1, capture2 = line:match('^(#+) (.+)')
vim.print(("First capture: %s, Second capture: %s"):format(capture1, capture2))
Using gsub¶
See lua patterns.
Using gsub is another way to use regex in Lua.
It accepts Lua "patterns."
gsub Syntax¶
The patterns use % as the escape character instead of \.
i.e., %1 - %9 for capture groups, and %0 for the entire match.
The replace_with field can be a string, a table, or a function.
If you specify a function, it'll be called for each match.
If replace_with is a string, then it is used as a replacement.
local text = "I love Lua!"
local newText = string.gsub(text, "Lua", "programming")
print(newText) -- Output: I love programming!
If replace_with is a table, then gsub queries the table with each
capture group, and when a matching key is found, it uses that as a replacement.
local text = "I love Lua and Python."
local replacements = { Lua = "Go", Python = "C" }
local newText = string.gsub(text, "(Lua) and (Python)", replacements)
print(newText) -- Output: I love Go and C.
If replace_with is a function, then it is called with the capture groups.
This function is called every time a match occurs, and all captured
substrings are passed as arguments (in order).
local text = "3 chickens, 5 cows, and 2 ducks"
local newText = string.gsub(text, "%d+", function(n) return tonumber(n) * 2 end)
print(newText) -- Output: 6 chickens, 10 cows, and 4 ducks
Another example using a function:¶
The pattern:
%$Matches literal dollar signs ($)(.-)is a non-greedy quantifier. This "lazy" matches as few characters as possible.
This pattern matches and captures any substring that starts
and ends with a $ character.
The match is then passed to the replacement function, which takes the captured substring as an argument.
-
The Replacement Function:
-
Instead of a simple replacement string, a function is provided as the replacement argument.
-
Lua calls this function for every match, passing the captured string as the argument
s. -
In this case,
swill receive the string"return 4+5"from between the$signs.
-
-
loadstringFunction:-
loadstring(s)is a function that compiles a string containing Lua code into a Lua function. -
In this context,
sis"return 4+5". - Note: In Lua 5.2 and later,
loadstringis replaced byload. However, the behavior is similar.
-
-
Executing the Compiled Code:
- The
()immediately followingloadstring(s)invokes the compiled function. - Since
sis"return 4+5", this compiled function, when called, evaluates the expression and returns9.
- The
-
Final Outcome:
- The final value of
xafter executing this snippet is"4+5 = 9", and the embedded Lua code within$...$is evaluated and replaced in the output string.