我正在尝试创建一个字符串模式,该模式将匹配非空格字符以及一组括号内的所有字符。例如,这样的序列:
local str = [[
This [pattern] should [return both] non-space
characters and [everything inside] brackets
]]
将打印出This
、[pattern]
、should
、[return Both]
、非空间
...等等。我已经研究了一段时间,并提出了一个非常接近的解决方案,我知道问题所在,但似乎无法解决。这是我的尝试:
local str = [[
This [pattern] should [return both] non-space
characters and [everything inside] brackets
]]
for s in string.gmatch(str, "%S+%[?.-%]?") do
print(s)
end
问题是括号内应允许有空格,但括号外不允许有空格。这将打印如下内容:This
、[pattern]
、should
、[return
、both]
、非空格
...等
请注意,[return
和 both]
是两个不同的捕获,而不是返回 [return Both]
。我对字符串模式还是比较陌生,所以我觉得有一些选项我可以忽略。不管怎样,如果有人对这类事情有经验,我肯定会很感激一些见解。
最佳答案
只是为了在评论中解释一下 Egor 的解决方案,关键思想是区分括号 []
内的空格与括号外的空格。这是通过以下方式完成的:
- 首先
gsub
将括号外的空格替换为\0
。 - 后跟与非空字符匹配的字符串的
gmatch
。
空字符 \0
用作标记,因为它不太可能与输入文本中的合法字符发生冲突。
此方法的一种变体是替换括号内的空格,而不是后面跟着非空格字符的匹配
for s in str:gsub("(%[.-%])",
function(x)
return x:gsub("%s+", "\0")
end)
:gmatch "%S+"
do
print( (s:gsub("%z+", " ")) )
end
请注意,您在解析期间创建中间字符串。如果输入字符串很长,那么临时中间字符串也很长。对于一次性比赛来说,这可能没问题。如果您正在处理更繁重的解析,我建议您查看 LPEG .
例如,以下lpeg.re语法可以解析给定的输入文本
local re = require 're'
local str =
[[
This [pattern] should [return both] non-space
characters and [everything inside brackets]
]]
local pat = re.compile
[[
match_all <- %s* match_piece+ !.
match_piece <- {word / bracket_word} %s*
word <- ([^]%s[])+
bracket_word <- '[' (word %s*)+ ']'
]]
for _, each in ipairs{ pat:match(str) } do
print(each)
end
输出:
This
[pattern]
should
[return both]
non-space
characters
and
[everything inside brackets]
关于regex - 在 Lua 中使用字符串模式获取一组括号内部和外部的字符串字符?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41926843/