6

有没有办法我可以做一个匹配的字符串模式,"ab|cd"以便它匹配输入字符串"ab""cd"输入字符串。我知道你使用类似"[ab]"模式的东西,它会匹配"a"or "b",但这只适用于一个字母的东西。

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

4

3 回答 3

5

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

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

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

于 2013-10-07T02:03:13.077 回答
4

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

输出:

你好
世界
你好
1000

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

于 2013-10-06T22:22:47.217 回答
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+
于 2013-10-07T01:45:07.267 回答