如何捕获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,这可以简单地检查(您可以检查任何局部变量,但它是常见的检查第一个。
如何提取字符串中由符号分隔的几个单词,以便在符号发生变化时不提取任何内容? 例如我写了这段代码:
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,这可以简单地检查(您可以检查任何局部变量,但它是常见的检查第一个。