Lua:全局匹配 {{{parameter}}} 或 {{{parameter|default}}} 形式的内容,捕获“pattern”和“default”,不会溢出

问题描述 投票:0回答:1

我正在尝试在维基百科模块中使用 Lua 模式匹配来定位 Mediawiki 参数语法的实例(例如

{{{parameter1-a|defaultValue}}}
{{{parameter1-a|{{{alias1-a|defaultValue}}}}}}
),以便将它们转换为 Lua 兼容的参数语法。 (是的,我完全知道为此使用模式匹配是不可原谅的危害人类罪,但无论如何。)

到目前为止,我有这个相对简单的模式,在大多数情况下效果很好:

"{{{([^{}<>|]+)(|?([^{}|]*))}}}"

(正则表达式等效 [希望],如果你想在 regex101 上测试:

/{{{([^{}<>|]+)(?:\|([^{}|]+)?)?}}}/g

但是,这不能正确匹配本身包含大括号的“默认”部分中的任何内容,因此我不能在默认中包含参数或模板 wiki 文本的别名。更具体地说:

  • 未经修改的正则表达式,如果给定像
    {{{parameter|{{{alias|default}}}}}}
    这样的东西,只会匹配/捕获{{{参数|{{{
    alias
    |
    default
    }}}
    }}}。
  • 删除大括号限制 (
    "{{{([^{}<>|]+)(|?([^{}|]*))}}}"
    ) 将成功获得
    {{{parameter|{{{alias}}}}}}
    ,按预期产生 {{{
    parameter
    |
    {{{alias}}}
    }}}
    ,但在别名上有默认值时它会给出 {{ {参数|{{{
    alias
    |
    default}}}
    }}}
  • 只需匹配所有内容 (
    "{{{([^{}<>|]+)(|?(.*))}}}"
    ) 与一个参数完美配合,但如果第一个参数有默认值,则有两个它会“溢出”:
    {{{parameter1|default}}} {{{parameter2}}}
    将产生 {{{
    parameter1
    |
    default}}} {{{parameter2
    }}}

我该如何解决这个问题?

lua string-matching lua-patterns wikitext
1个回答
0
投票

这似乎是 Lua 特殊括号匹配模式项的完美用例

%b
!使用
%b{}
,你可以匹配一对匹配的花括号。通过在每一侧用两个花括号包围它,您可以匹配三对花括号。

鉴于您的测试用例:

local text = [[
lorem ipsum dolor sit amet
{{{blarg}}}
lorem ipsum dolor sit amet
{{{blarg|default}}}
lorem ipsum dolor sit amet
{{{parameter1-a|{{{alias1-a|defaultValue}}}}}}
]]

并在

{{%b{}}}
中使用模式
gmatch

for match in text:gmatch"{{%b{}}}" do
    print(match)
end

你得到

{{{blarg}}}
{{{blarg|default}}}
{{{parameter1-a|{{{alias1-a|defaultValue}}}}}}

如预期。然后你可以进一步处理这个参数:

local content = match:sub(4, -4) -- cut off curly braces
local param, default = match:match"^([^|]+)|([^|]+)$"
if not param then param = content end -- no default

(我在这里稍微简化了你的模式,这并不完全等同;它更宽松)

© www.soinside.com 2019 - 2024. All rights reserved.