Lua 5.1,LPeg v0.12
do
local p = re.compile([[
pattern <- ( {b} / {escaped} / brackets / other)+
b <- "%b" . .
escaped <- "%" .
brackets <- { "[" ([^]%]+ / escaped)* "]" }
other <- [^[%]+ -> cases
]], {
cases = function(str) return (str:gsub('%a',function(a) return '['..a:lower()..a:upper()..']' end)) end
})
local pb = re.compile([[
pattern <- ( {b} / {escaped} / brackets / other)+
b <- "%b" . .
escaped <- "%" .
brackets <- {: {"["} ({escaped} / bcases)* {"]"} :}
bcases <- [^]%]+ -> bcases
other <- [^[%]+ -> cases
]], {
cases = function(str) return (str:gsub('%a',function(a) return '['..a:lower()..a:upper()..']' end)) end
, bcases = function(str) return (str:gsub('%a',function(a) return a:lower()..a:upper() end)) end
})
function iPattern(pattern,brackets)
('sanity check'):find(pattern)
return table.concat({re.match(pattern, brackets and pb or p)})
end
end
local test = '[ab%c%]d%%]+ o%%r %bnm'
print(iPattern(test))
print(iPattern(test,true))
print(('qwe [%D]% O%r n---m asd'):match(iPattern(test, true)))
纯Lua版本:
为了将字符串转换为正确的模式,必须分析字符串中的所有字符,因为Lua模式不像正则表达式(abc|something)那样具有替代项。
function iPattern(pattern, brackets)
('sanity check'):find(pattern)
local tmp = {}
local i=1
while i <= #pattern do
local char = pattern:sub(i,i)
if char == '%' then
tmp[#tmp+1] = char
i=i+1
char = pattern:sub(i,i)
tmp[#tmp+1] = char
if char == 'b' then
tmp[#tmp+1] = pattern:sub(i+1,i+2)
i=i+2
end
elseif char=='[' then
tmp[#tmp+1] = char
i = i+1
while i <= #pattern do
char = pattern:sub(i,i)
if char == '%' then
tmp[#tmp+1] = char
tmp[#tmp+1] = pattern:sub(i+1,i+1)
i = i+1
elseif char:match("%a") then
tmp[#tmp+1] = not brackets and char or char:lower()..char:upper()
else
tmp[#tmp+1] = char
end
if char==']' then break end
i = i+1
end
elseif char:match("%a") then
tmp[#tmp+1] = '['..char:lower()..char:upper()..']'
else
tmp[#tmp+1] = char
end
i=i+1
end
return table.concat(tmp)
end
local test = '[ab%c%]d%%]+ o%%r %bnm'
print(iPattern(test))
print(iPattern(test,true))
print(('qwe [%D]% O%r n---m asd'):match(iPattern(test, true)))
letter:lower
一样使用pattern:gsub
。甚至可以使用('[%s%s]'):format
,但那有点奇怪。 - Mudstring.format(...)
看起来比('[%s%s]'):format(...)
更熟悉,但我更喜欢pattern:gsub(...)
!谢谢。 - Bart Kiers%%test
转换为%%[tT]est
?这个匹配被跳过了,因为之前的迭代已经匹配了两个'%%'吗?也许我的大脑今天有点疲惫 :/ - Nubbychadnezzar%%test
被转换为%%[tT][eE][sS][tT]
。一旦一个模式匹配成功,它将不会成为另一个匹配的一部分。因此,%%test
有5个匹配项:%%
、t
、e
、s
和t
。%%
保持不变,并且字母被转换为[tT]
、[eE]
... - Bart Kiers