如何捕获lua中符号之间的字符串?

How to capture a string between signs in lua?

如何提取字符串中由符号分隔的几个单词,以便在符号发生变化时不提取任何内容? 例如我写了这段代码:

function split(str) 
 result = {};
for match in string.gmatch(str, "[^%<%|:%,%FS:%>,%s]+" ) do
 table.insert(result, match);
end

return result
end
--------------------------Example--------------------------------------------
str = "<busy|MPos:-750.222,900.853,1450.808|FS:2,10>"

my_status={}

status=split(str)

for key, value in pairs(status) do
    table.insert(my_status,value)
end

print(my_status[1]) -- 
print(my_status[2]) -- 
print(my_status[3]) -- 
print(my_status[4]) -- 
print(my_status[5]) --
print(my_status[6]) -- 
print(my_status[7]) -- 

输出:

busy
MPos
-750.222
900.853
1450.808
2
10

这段代码工作正常,但是如果 str 字符串中的字符和文本发生变化,提取仍然完成,这是我不希望的。

如果字符串变为

str = "Hello stack overFlow"

输出:

Hello
stack
over
low
nil
nil
nil

换句话说,如果字符串是这种格式,我只想提取:"<busy|MPos:-750.222,900.853,1450.808|FS:2,10>"

在 lua 模式中,您可以使用捕获,这非常适合此类情况。我使用如下内容:

--------------------------Example--------------------------------------------     
str = "<busy|MPos:-750.222,900.853,1450.808|FS:2,10>"     
local status, mpos1, mpos2, mpos3, fs1, fs2  = string.match(str, "%<(%w+)%|MPos:(%--%d+%.%d+),(%--%d+%.%d+),(%--%d+%.%d+)%|FS:(%d+),(%d+)%>")     
print(status, mpos1, mpos2, mpos3, fs1, fs2)  

我在这里使用 string.match,而不是 string.gmatch,因为我们没有任意数量的条目(如果是这种情况,您必须采用不同的方法)。让我们分解一下模式:所有 captures 都被括号 () 包围并得到 returned,因此 return 值与 captures 一样多。个人捕获是:

  • 状态标志(或其他):busy 是一个简单的词,因此我们可以使用 %w 字符 class(字母数字字符,可能是 %a,仅字母也可以)。然后应用 + 运算符(您已经知道那个)。 + 捕获
  • MPos 条目的三个数字每个都得到 (%--%d+%.%d+),乍一看这看起来很奇怪。我在任何 non-alphanumeric 字符前使用 %,因为它将所有魔法字符(例如 + 变成普通字符)。 - 是一个魔法字符,所以这里需要匹配文字 -,但是 lua 允许把它放在 any 前面 non-alphanumerical character,我就是这样做的。所以减号是可选的,所以捕获以 %-- 开始,它是文字 - (%-) 的一次或零次重复(- 运算符)。然后我只匹配两个由点分隔的整数(%d 是一个数字,%. 匹配一个文字点)。我们这样做三次,用逗号分隔(我不会转义,因为我确定它不是魔法字符)。
  • 最后一个条目 (FS) 与 MPos 条目
  • 几乎相同
  • 所有条目都用|分隔,我简单匹配%|

所以放在一起:

        start of string: %<                                                                     
           status field:   (%w+)   
              separator:        %|
   MPos (three numbers):          MPos:(%--%d+%.%d+),(%--%d+%.%d+),(%--%d+%.%d+)
              separator:                                                        %|
FS entry (two integers):                                                          FS:(%d+),(%d+)
          end of string:                                                                        %>   

通过这种方法,您可以在具有合理名称的局部变量中获取数据,然后您可以将其放入 table(例如)。

如果匹配失败(例如,当您使用 "Hello stack overFlow"), nil` 时 returned,这可以简单地检查(您可以检查任何局部变量,但它是常见的检查第一个。