String Lua:除非被引用,否则将字符串拆分为单词
因此,我使用以下代码在空格之间分割字符串:String Lua:除非被引用,否则将字符串拆分为单词,string,lua,lua-patterns,String,Lua,Lua Patterns,因此,我使用以下代码在空格之间分割字符串: text = "I am 'the text'" for string in text:gmatch("%S+") do print(string) end 结果是: I am 'the text' 但我需要这样做: I am the text --[[yep, without the quotes]] 我该怎么做 编辑:为了补充这个问题,我们的想法是将参数从一个程序传递到另一个程序。下面是我正在处理的请求,目前正在审查中:通过巧妙的解析
text = "I am 'the text'"
for string in text:gmatch("%S+") do
print(string)
end
结果是:
I
am
'the
text'
但我需要这样做:
I
am
the text --[[yep, without the quotes]]
我该怎么做
编辑:为了补充这个问题,我们的想法是将参数从一个程序传递到另一个程序。下面是我正在处理的请求,目前正在审查中:通过巧妙的解析可能有办法做到这一点,但另一种方法可能是跟踪简单的状态,并基于对引用片段的检测合并片段。类似的方法可能会奏效:
local text = [[I "am" 'the text' and "some more text with '" and "escaped \" text"]]
local spat, epat, buf, quoted = [=[^(['"])]=], [=[(['"])$]=]
for str in text:gmatch("%S+") do
local squoted = str:match(spat)
local equoted = str:match(epat)
local escaped = str:match([=[(\*)['"]$]=])
if squoted and not quoted and not equoted then
buf, quoted = str, squoted
elseif buf and equoted == quoted and #escaped % 2 == 0 then
str, buf, quoted = buf .. ' ' .. str, nil, nil
elseif buf then
buf = buf .. ' ' .. str
end
if not buf then print((str:gsub(spat,""):gsub(epat,""))) end
end
if buf then print("Missing matching quote for "..buf) end
这将打印:
I
am
the text
and
some more text with '
and
escaped \" text
已更新以处理混合引号和转义引号。更新以删除引号。已更新以处理引用的单词。请尝试以下操作:
text = [[I am 'the text' and '' here is "another text in quotes" and this is the end]]
local e = 0
while true do
local b = e+1
b = text:find("%S",b)
if b==nil then break end
if text:sub(b,b)=="'" then
e = text:find("'",b+1)
b = b+1
elseif text:sub(b,b)=='"' then
e = text:find('"',b+1)
b = b+1
else
e = text:find("%s",b+1)
end
if e==nil then e=#text+1 end
print("["..text:sub(b,e-1).."]")
end
Lua模式无法正确处理此任务。下面是一个改编自的解决方案。它处理单引号和双引号
local lpeg = require 'lpeg'
local P, S, C, Cc, Ct = lpeg.P, lpeg.S, lpeg.C, lpeg.Cc, lpeg.Ct
local function token(id, patt) return Ct(Cc(id) * C(patt)) end
local singleq = P "'" * ((1 - S "'\r\n\f\\") + (P '\\' * 1)) ^ 0 * "'"
local doubleq = P '"' * ((1 - S '"\r\n\f\\') + (P '\\' * 1)) ^ 0 * '"'
local white = token('whitespace', S('\r\n\f\t ')^1)
local word = token('word', (1 - S("' \r\n\f\t\""))^1)
local string = token('string', singleq + doubleq)
local tokens = Ct((string + white + word) ^ 0)
input = [["This is a string" 'another string' these are words]]
for _, tok in ipairs(lpeg.match(tokens, input)) do
if tok[1] ~= "whitespace" then
if tok[1] == "string" then
print(tok[2]:sub(2,-2)) -- cut off quotes
else
print(tok[2])
end
end
end
输出:
This is a string
another string
these
are
words
我更喜欢使用字符串解析。无论如何,虽然我在帖子中没有说我需要一些东西来处理单引号和双引号,因为这段代码的思想是从shell解析参数;只需将
“^
”`替换为[[[^[“]]]
,将“$”
替换为[[[“]$]
。您可能还需要检查开始引号是否与结束引号匹配。可以使用字符串解析,但解决方案可能更复杂(并且不是使用一个表达式,因为Lua模式的功能不足以表达您所需的内容)。@m45t3r,我更新了代码以处理混合引号和转义引号。嗯,我们确实以另一种方式解决了这个问题(使用mpv的内部键值对表示而不是传递字符串),但我非常喜欢您的答案(因为它不需要另一个库,而且代码比其他非库答案更干净),所以我将此标记为答案。修复了处理单引号和双引号的问题,和空引用文本。