Lua string.match() 问题

发布于 2024-11-14 00:56:51 字数 589 浏览 4 评论 0原文

我想匹配几行字符串和一些数字。 这些行可以看起来像

"  Code                                             : 75.570 "

or

"  ..dll                                   :          13.559       1"

or

"  ..node                                    :  4.435    1.833    5461"

or or

"  ..NavRegions                                     :  0.000         "

我想要类似的东西

local name, numberLeft, numberCenter, numberRight = line:match("regex");

,但我对字符串匹配非常陌生。

I want to match a few lines for a string and a few numbers.
The lines can look like

"  Code                                             : 75.570 "

or

"  ..dll                                   :          13.559       1"

or

"  ..node                                    :  4.435    1.833    5461"

or

"  ..NavRegions                                     :  0.000         "

I want something like

local name, numberLeft, numberCenter, numberRight = line:match("regex");

But I'm very new to the string matching.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

葬花如无物 2024-11-21 00:56:51

此模式适用于所有情况:

%s*([%w%.]+)%s*:%s*([%d%.]+)%s*([%d%.]* )%s*([%d%.]*)

简短说明:[] 构成一组字符(例如小数)。最后一个数字使用 [set]* 因此空匹配也是有效的。这样,未找到的数字将被有效地分配nil

请注意在模式中使用 + - * 之间的区别。有关模式的更多信息请参见 Lua 参考

这将匹配点和小数的任意组合,因此稍后尝试使用 tonumber() 将其转换为数字可能会很有用。

一些测试代码:

s={
"  Code                                             : 75.570 ",
"  ..dll                                   :          13.559       1",
"  ..node                                    :  4.435    1.833    5461",
"  ..NavRegions                                     :  0.000         "
}
for k,v in pairs(s) do
    print(v:match('%s*([%w%.]+)%s*:%s*([%d%.]+)%s*([%d%.]*)%s*([%d%.]*)'))
end

This pattern will work for every case:

%s*([%w%.]+)%s*:%s*([%d%.]+)%s*([%d%.]*)%s*([%d%.]*)

Short explanation: [] makes a set of characters (for example the decimals). The last to numbers use [set]* so an empty match is valid too. This way the number that haven't been found will effectively be assigned nil.

Note the difference between using + - * in patterns. More about patterns in the Lua reference.

This will match any combination of dots and decimals, so it might be useful to try and convert it to a number with tonumber() afterwards.

Some test code:

s={
"  Code                                             : 75.570 ",
"  ..dll                                   :          13.559       1",
"  ..node                                    :  4.435    1.833    5461",
"  ..NavRegions                                     :  0.000         "
}
for k,v in pairs(s) do
    print(v:match('%s*([%w%.]+)%s*:%s*([%d%.]+)%s*([%d%.]*)%s*([%d%.]*)'))
end
清醇 2024-11-21 00:56:51

这是一个起点:

s="  ..dll                                   :          13.559       1"
for w in s:gmatch("%S+") do
        print(w)
end

当然,您可以将这些单词保存在表格中而不是打印。并跳过第二个单词。

Here is a starting point:

s="  ..dll                                   :          13.559       1"
for w in s:gmatch("%S+") do
        print(w)
end

You may save these words in a table instead of printing, of course. And skip the second word.

吖咩 2024-11-21 00:56:51

@Ihf谢谢你,我现在有了一个可行的解决方案。

local moduleInfo, name = {};
for word in line:gmatch("%S+") do
    if (word~=":") then
        word = word:gsub(":", "");
        local number = tonumber(word);
        if (number) then
            moduleInfo[#moduleInfo+1] = number;
        else
            if (name) then
                name = name.." "..word:gsub("%$", "");
            else
                name = word:gsub("%$", "");
            end
        end
    end
end

@jpjacobs 真的很好,也谢谢。我会出于综合原因重写我的代码;-) 当然,我会实现你的正则表达式。

@Ihf Thank you, I now have a working solution.

local moduleInfo, name = {};
for word in line:gmatch("%S+") do
    if (word~=":") then
        word = word:gsub(":", "");
        local number = tonumber(word);
        if (number) then
            moduleInfo[#moduleInfo+1] = number;
        else
            if (name) then
                name = name.." "..word:gsub("%$", "");
            else
                name = word:gsub("%$", "");
            end
        end
    end
end

@jpjacobs Really nice, thanks too. I'll rewrite my code for synthetic reasons ;-) I'll implement your regex of course.

随遇而安 2024-11-21 00:56:51

我不懂Lua语言,所以我不会帮助你。
但在 Java 中,这个正则表达式应该与您的输入匹配

"([az]*)\\s+:\\s+([\\.\\d]*)?\\s+([\\.\\d] *)?\\s+([\\.\\d]*)?"

你必须测试每个组才能知道是否有数据 left, center, right

看一下 Lua,它可能看起来像这样。不能保证,我没有看到如何转义 . (点),它具有特殊含义,并且如果 ? 在 Lua 中可用,也不会转义。

“([az]*)%s+:%s+([%.%d]*)?%s+([%.%d]*)?%s+([%.%d]*)?”

I have no understanding of the Lua language, so I won't help you there.
But in Java this regex should match your input

"([a-z]*)\\s+:\\s+([\\.\\d]*)?\\s+([\\.\\d]*)?\\s+([\\.\\d]*)?"

You have to test each group to know if there is data left, center, right

Having a look at Lua, it could look like this. No guarantee, I did not see how to escape . (dot) which has a special meaning and also not if ? is usable in Lua.

"([a-z]*)%s+:%s+([%.%d]*)?%s+([%.%d]*)?%s+([%.%d]*)?"

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文