【问题标题】:Lua string manipulation pattern matching alternative "|"Lua 字符串操作模式匹配替代“|”
【发布时间】:2013-10-13 09:50:43
【问题描述】:

有没有办法我可以创建一个匹配 "ab|cd" 的字符串模式,以便匹配输入字符串中的 "ab""cd"。我知道您使用 "[ab]" 之类的东西作为模式,它将匹配 "a""b",但这仅适用于一个字母。

请注意,我的实际问题要复杂得多,但本质上我只需要知道 Lua 的字符串操作中是否存在 OR 事物。我实际上想在 OR 事物的每一侧放置其他模式,等等。但如果它与 "hello|world" 之类的东西一起使用,并且将 "hello, world!""hello""world" 匹配,那就太好了!

【问题讨论】:

  • 我不确定使用内置模式匹配是否可以轻松完成。如果您需要使用 Lua 执行复杂的解析/匹配,您可以尝试 lpeg:inf.puc-rio.br/~roberto/lpeg
  • @peterm 是的,使用 lpeg 很容易! (lpeg.P("foo") + "bar"):match(input)

标签: string parsing lua lua-patterns


【解决方案1】:

在 Lua 模式中使用逻辑运算符可以解决大多数问题。例如,对于正则表达式[hello|world]%d+,您可以使用

string.match(str, "hello%d+") or string.match(str, "world%d+")

or运算符的快捷电路确保字符串首先匹配hello%d+,如果失败则匹配world%d+

【讨论】:

    【解决方案2】:

    很遗憾,Lua patterns 不是正则表达式,功能较弱。特别是它们不支持交替(Java 或 Perl 正则表达式的竖线 | 运算符),这是您想要做的。

    一个简单的解决方法可能如下:

    local function MatchAny( str, pattern_list )
        for _, pattern in ipairs( pattern_list ) do
            local w = string.match( str, pattern )
            if w then return w end
        end
    end
    
    
    s = "hello dolly!"
    print( MatchAny( s, { "hello", "world", "%d+" } ) )
    
    s = "cruel world!"
    print( MatchAny( s, { "hello", "world", "%d+" } ) )
    
    s = "hello world!"
    print( MatchAny( s, { "hello", "world", "%d+" } ) )
    
    s = "got 1000 bucks"
    print( MatchAny( s, { "hello", "world", "%d+" } ) )
    

    输出:

    你好 世界 你好 1000

    函数MatchAny 将匹配它的第一个参数(一个字符串)与一个 Lua 模式列表并返回第一个成功匹配的结果。

    【讨论】:

      【解决方案3】:

      为了扩展peterm 的建议,lpeg 还提供了一个re 模块,该模块公开了与lua 的标准string 库类似的接口,同时仍保留了lpeg 提供的额外功能和灵活性。

      我会说首先尝试re 模块,因为它的语法与 lpeg 相比没有那么深奥。这是一个可以与您的 hello world 示例匹配的示例用法:

      dump = require 'pl.pretty'.dump
      re = require 're'
      
      
      local subj = "hello, world! padding world1 !hello hello hellonomatch nohello"
      pat = re.compile [[
        toks  <-  tok (%W+ tok)*
        tok   <-  {'hello' / 'world'} !%w / %w+
      ]]
      
      res = { re.match(subj, pat) }
      dump(res)
      

      会输出:

      {
        "hello",
        "world",
        "hello",
        "hello"
      }
      

      如果您对捕获匹配的位置感兴趣,只需稍微修改语法以进行位置捕获:

      tok   <-  {}('hello' / 'world') !%w / %w+
      

      【讨论】:

        猜你喜欢
        • 2018-03-11
        • 2021-06-07
        • 2011-03-29
        • 1970-01-01
        • 1970-01-01
        • 2015-05-26
        • 2013-04-18
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多