Lua字符串操作模式匹配替代“|”

时间:2013-10-06 21:51:12

标签: string parsing lua lua-patterns

我是否可以使用匹配"ab|cd"的字符串模式,以便它匹配输入字符串中的"ab""cd"。我知道您使用类似"[ab]"的内容作为模式,它会匹配"a""b",但这只适用于一个字母的内容。

请注意,我的实际问题要复杂得多,但基本上我只需要知道Lua的字符串操作是否存在OR问题。我实际上想要在OR事物的每一侧放置其他模式等等。但是如果它适用于"hello|world"并且"hello, world!""hello"和{{1}匹配那太棒了!

3 个答案:

答案 0 :(得分:3)

不幸的是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+" } ) )

<强>输出:

hello
world
hello
1000

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

答案 1 :(得分: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+

答案 2 :(得分:3)

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

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

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