如何在字符串中提取由符号分隔的几个单词,以便在符号更改时不提取任何内容?例如,我写了以下代码:
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 '),可以简单地检查(您可以检查任何局部变量,但通常检查第一个)。