【问题标题】:Pattern Matching with Lua's string module使用 Lua 的字符串模块进行模式匹配
【发布时间】:2009-07-17 01:16:30
【问题描述】:

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

较长形式的输入字符串如下所示:

本地用户输入 = "x|y|z"

其中x、y 和z 可以是任何字符或什么都不是(空字符串,即"")和 z 也可以包含竖线/竖线 - 我只想根据遇到的前两个竖线 ("|") 将字符串分成三个部分。困难在于用户也不能使用该表单-他或她可以简单地输入"x"或"x||z"或"||z"等。在这种情况下,我仍然需要获取x的值,@ 987654332@,和z,并且应该清楚它们被分配给了哪些变量。

例如,我试过这个:

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

首先请注意,这甚至无法正确获取a、b 和c。但更重要的是,当usermsg 只是"x" 时,它会将x 的值设置为变量c,而应该是a。而当用户输入"x|y"时,变量a是x(正确)而变量c是y(错了,应该赋值给变量b)。

然后我试着分开做:

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

但这也失败了。它匹配x,但不匹配y,并且c 最终成为y 加上管道和z。

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

【问题讨论】:

    标签: string lua find design-patterns


    【解决方案1】:

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

    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
                -- if max > #(all ocurances of delim in str), we end here      
                break
            end
            table.insert( result, str:sub( last, start-1 ) )
            last = stop+1
            max = max - 1
        end
        -- add the rest
        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'
    

    【讨论】:

      【解决方案2】:

      这应该可以按您的意愿工作

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

      【讨论】:

      • 如果用户输入是 "a|b|c" 则返回 a = "a" b = "a" c = "|b|c"
      • 您使用的是什么版本的 LUA?我正在 v5.1.4 上对其进行测试,它正在返回预期值。
      【解决方案3】:

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

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

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

      【讨论】:

        猜你喜欢
        • 2021-06-07
        • 2011-03-29
        • 1970-01-01
        • 2018-03-11
        • 2013-09-08
        • 1970-01-01
        • 1970-01-01
        • 2013-10-13
        • 1970-01-01
        相关资源
        最近更新 更多