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

有没有一种方法可以使用字符串模式匹配 "ab|cd",以便在输入字符串中匹配 "ab""cd"。 我知道可以使用类似 "[ab]" 这样的模式来匹配 "a""b", 但这仅适用于单个字母。

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

点赞
用户2633423
用户2633423

不幸的是,Lua模式不是正则表达式,且功能更少。特别地,它们不支持备选(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模式列表匹配,并返回第一个成功匹配的结果。

2013-10-06 22:22:47
用户234175
用户234175

仅是扩展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+
2013-10-07 01:45:07
用户1009479
用户1009479

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

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

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

2013-10-07 02:03:13