使用Lua的字符串模块进行模式匹配

我正在尝试在 Lua 中使用 string.find 来解析用户输入字符串的内容。我试图查找最多三个不同的参数(如果用户输入了它们),但有时只有一个。

输入字符串在其更长的形式下看起来像:

local userInput = "x|y|z"

其中 xyz 可以是任何字符或空白(空字符串,即 ""),而 z 还可以包含垂直条/管 - 我只想基于遇到的前两个垂直杠("|")将字符串分成三个部分。困难在于用户也可以不使用该形式 - 他或她可以输入简单地 "x""x||z""||z" 等。在这些情况下,我仍需要获取 xyz 的值,并且应该清楚它们分别分配给哪些变量。

例如,我尝试了这个:

local _,_,a,b,c = string.find(usermsg, "([^|]*)|?([^|]*)|?(.+)")

首先注意到这并没有正确地获取 abc。但更重要的是,当 usermsg 只是 "x" 时,它将 x 的值设置为变量 c,而不是 a。并且当用户键入 "x|y" 时,变量 ax(正确的),但变量 cy(错误的,应该分配给变量 b)。

然后我试图分开做:

local _,_,a = string.find(usermsg , "([^|]+)|?[^|]*|?.*")
local _,_,b= string.find(usermsg , "[^|]*|([^|]+)|?.*")
local _,_,c= string.find(usermsg , "[^|]*|[^|]*|(.+)")

但这也失败了。它匹配了 x,但没有匹配 y,而 c 最终变成了 y 加上管道和 z

任何帮助都将不胜感激。谢谢! :)

原文链接 https://stackoverflow.com/questions/1141069

点赞
stackoverflow用户881229
stackoverflow用户881229

这应该可以按你想要的方式工作

local _,_,a,b = string.find(usermsg, "([^|]*)|?(.*)")
local _,_,b,c = string.find(b, "([^|]*)|?(.*)")
2009-07-17 02:10:57
stackoverflow用户95612
stackoverflow用户95612

似乎您只是在寻找带最大分割次数的典型拆分函数。这是我的函数:

function string.split( str, delim, max, special )
    if max == nil then max = -1 end
    if delim == nil then delim = " " end
    if special == nil then special = False end
    local last, start, stop = 1
    local result = {}
    while max ~= 0 do
        start, stop = str:find(delim, last, not special )
        if start == nil then
            -- 如果 max 大于 str 中分隔符的数量,则到这里结束
            break
        end
        table.insert( result, str:sub( last, start-1 ) )
        last = stop+1
        max = max - 1
    end
    -- 添加剩余部分
    table.insert( result, str:sub( last ) )
    return result
end

print( ("A='%s' B='%s' C='%s'"):format(unpack( ("hello|there|world"):split('|', 2) )))
print( ("A='%s' B='%s' C='%s'"):format(unpack( ("||world"):split('|', 2) )))
print( ("A='%s' B='%s' C='%s'"):format(unpack( ("hello||world"):split('|', 2) )))
print( ("A='%s' B='%s' C='%s'"):format(unpack( ("hello|there|"):split('|', 2) )))
print( ("A='%s' B='%s' C='%s'"):format(unpack( ("hello||world|and|the|rest"):split('|', 2) )))

=>

A='hello' B='there' C='world'
A='' B='' C='world'
A='hello' B='' C='world'
A='hello' B='there' C=''
A='hello' B='' C='world|and|the|rest'
2009-07-24 21:24:41
stackoverflow用户3524201
stackoverflow用户3524201

我认为解决这个问题的最佳方案是 string.match

local a, b, c = string.match("(^|*)|(^|*)|(.*)")

^| 匹配任何不是 | 的内容, * 表示它将匹配0个或多个。

2016-09-02 18:38:32