如何在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 = "Hello stack overFlow"

输出:

Hello
stack
over
low
nil
nil
nil

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

在lua模式中,您可以使用capture,它非常适合这样的事情。我使用如下代码:

--------------------------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,因为我们没有任意数量的条目(如果是这种情况,您必须采用不同的方法)。让我们分解该模式:所有捕获都被括号()包围并返回,因此有与捕获一样多的返回值。单个捕获是:

  • 状态标志(或其他什么):busy是一个简单的单词,所以我们可以使用%w字符类(字母数字字符,可能是%a,只有字母也可以)。然后应用+操作符(您已经知道这个操作符)。+在捕获
  • MPos条目的三个数字都是(%--%d+%.%d+),乍一看很奇怪。我在任何非字母数字字符前面使用%,因为它将所有魔术字符(如+)转换为普通字符。-是一个魔术字符,所以这里需要匹配文字-,但是lua允许将它放在任何非字母数字字符的前面,我就是这样做的。所以减号是可选的,所以捕获从%--开始,它是字面量-(%-)的一次或零次重复(-运算符)。然后我只匹配两个由点分隔的整数(%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:                                                                        %>   

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

如果匹配失败(例如,当您使用"Hello stack overFlow"),时,返回nil '),可以简单地检查(您可以检查任何局部变量,但通常检查第一个)。

相关内容

  • 没有找到相关文章

最新更新