86 lines
1.9 KiB
Lua
86 lines
1.9 KiB
Lua
|
local lowers = {}
|
||
|
local uppers = {}
|
||
|
for c in ('abcdefghijklmnopqrstuvwxyz'):gmatch '.' do
|
||
|
lowers[c] = true
|
||
|
uppers[c:upper()] = true
|
||
|
end
|
||
|
|
||
|
---@param input string
|
||
|
---@param other string
|
||
|
local function isValidFirstChar(input, other)
|
||
|
local first = input:sub(1, 1):upper()
|
||
|
if first == other:sub(1, 1):upper() then
|
||
|
return true
|
||
|
end
|
||
|
local pos = other:find(first, 2, true)
|
||
|
if not pos and uppers[first] then
|
||
|
-- word after symbol?
|
||
|
if other:find('%A' .. first:lower(), 2) then
|
||
|
return true
|
||
|
end
|
||
|
end
|
||
|
if not pos then
|
||
|
return false
|
||
|
end
|
||
|
local char = other:sub(pos, pos)
|
||
|
-- symbol?
|
||
|
if not uppers[char] then
|
||
|
return true
|
||
|
end
|
||
|
-- word boundary?
|
||
|
local beforeChar = other:sub(pos - 1, pos - 1)
|
||
|
if not uppers[beforeChar] then
|
||
|
return true
|
||
|
end
|
||
|
return false
|
||
|
end
|
||
|
|
||
|
local function isAlmostSame(input, other)
|
||
|
local lMe = input:lower()
|
||
|
local lOther = other:lower()
|
||
|
if lMe == lOther:sub(1, #lMe) then
|
||
|
return true
|
||
|
end
|
||
|
local chars = {}
|
||
|
for i = 1, #lOther do
|
||
|
local c = lOther:sub(i, i)
|
||
|
chars[c] = (chars[c] or 0) + 1
|
||
|
end
|
||
|
for i = 1, #lMe do
|
||
|
local c = lMe:sub(i, i)
|
||
|
if chars[c] and chars[c] > 0 then
|
||
|
chars[c] = chars[c] - 1
|
||
|
else
|
||
|
return false
|
||
|
end
|
||
|
end
|
||
|
return true
|
||
|
end
|
||
|
|
||
|
---@param input string
|
||
|
---@param other string
|
||
|
---@param fast? boolean
|
||
|
---@return boolean isMatch
|
||
|
---@return number deviation
|
||
|
return function (input, other, fast)
|
||
|
if input == other then
|
||
|
return true, 0
|
||
|
end
|
||
|
if input == '' then
|
||
|
return true, 0
|
||
|
end
|
||
|
if #input > #other then
|
||
|
return false, 0
|
||
|
end
|
||
|
if fast and input:sub(1, 1) ~= other:sub(1, 1) then
|
||
|
return false, 0
|
||
|
end
|
||
|
if not isValidFirstChar(input, other) then
|
||
|
return false, 0
|
||
|
end
|
||
|
if not isAlmostSame(input, other) then
|
||
|
return false, 0
|
||
|
end
|
||
|
return true, 1
|
||
|
end
|