我目前正在学习lua。关于 lua 中的模式匹配,我在 lua.org 上的 lua 文档中找到了以下句子:
尽管如此,Lua 中的模式匹配是一个强大的工具,并且包含一些标准 POSIX 实现难以匹配的特性。
因为我熟悉 posix 正则表达式,所以我想知道是否有任何常见的示例,其中 lua 模式匹配与正则表达式相比“更好”——还是我误解了这个句子?如果有任何常见的例子:为什么模式匹配与正则表达式更适合?
我目前正在学习lua。关于 lua 中的模式匹配,我在 lua.org 上的 lua 文档中找到了以下句子:
尽管如此,Lua 中的模式匹配是一个强大的工具,并且包含一些标准 POSIX 实现难以匹配的特性。
因为我熟悉 posix 正则表达式,所以我想知道是否有任何常见的示例,其中 lua 模式匹配与正则表达式相比“更好”——还是我误解了这个句子?如果有任何常见的例子:为什么模式匹配与正则表达式更适合?
与正则表达式相比,lua 模式匹配是否“更好”的任何常见示例?
Lua 模式比 POSIX 正则表达式具有更高的信噪比,这并不是特别的例子。通常更可取的是整体设计,而不是特定示例。
以下是一些有助于良好设计的因素:
用于匹配常见字符类型的非常轻量级的语法,包括大写字母 ( %u
)、十进制数字 ( %d
)、空格字符 ( %s
) 等。任何字符类型都可以通过使用相应的大写字母来补充,因此模式%S
匹配任何非空格字符。
报价非常简单且规律。引用字符是%
,因此它始终与字符串引用字符 不同\
,这使得 Lua 模式比 POSIX 正则表达式更容易阅读(当需要引用时)。引用符号总是安全的,而且从来没有必要引用字母,所以你可以按照这个经验法则而不是记住什么符号是特殊的元字符。
Lua 提供“捕获”并且可以返回多个捕获作为match
调用的结果。这个接口比通过副作用捕获子字符串或具有一些必须被询问才能找到捕获的隐藏状态要好得多。捕获语法很简单:只需使用括号。
Lua 有一个“最短匹配”-
修饰符与“最长匹配”*
运算符一起使用。因此,例如s:find '%s(%S-)%.'
,查找前面是空格并后面跟一个点的非空格字符的最短序列。
Lua 模式的表达能力与 POSIX “基本”正则表达式相当,没有交替运算符|
。你放弃的是“扩展”正则表达式|
。如果您需要如此强大的表达能力,我建议您一直使用LPEG,它本质上以相当合理的成本为您提供了上下文无关语法的强大功能。
http://lua-users.org/wiki/LibrariesAndBindings包含功能列表,如果您希望继续使用它们,包括正则表达式库。
为了回答这个问题(请注意,我绝不是 Lua 大师),该语言具有在嵌入式应用程序中使用的悠久传统,其中完整的正则表达式引擎会过度增加平台上使用的代码的大小,有时比整个 Lua 库本身都要大得多。
[编辑] 我刚刚在 Lua 编程的在线版本(学习语言的极好资源)中发现,这是由语言的一个原则描述的:请参阅下面的评论 [/编辑]
我个人发现 Lua 提供的默认模式匹配满足了我的大部分 regex-y 需求。你的旅费可能会改变。
好的,只是这个讨论的一个小菜鸟笔记;我特别对这个页面感到困惑:
因为那个说\s
匹配空格,正如我从其他正则表达式语法中知道的那样......所以我在shell中尝试它:
$ lua
Lua 5.1.4 Copyright (C) 1994-2008 Lua.org, PUC-Rio
> c=" d"
> print(c:match(" "))
> print(c:match("."))
> print(c:match("\s"))
nil
> print("_".. c:match("[ ]") .."_")
_ _
> print("_".. c:match("[ ]*") .."_")
_ _
> print("_".. c:match("[\s]*") .."_")
__
嗯......似乎\s
在这里没有得到认可 - 所以该页面可能指的是 Scite 的 Find/Replace 中的正则表达式 - 而不是 Lua 的正则表达式语法(scite 也使用)。
然后我重新阅读了 lua-users wiki: Patterns Tutorial,并开始得到关于转义字符的评论%
,而不是\
在@NormanRamsey的答案中。所以,试试这个:
> print("_".. c:match("[%s]*") .."_")
_ _
...确实有效。
所以,正如我最初认为 Lua 的“模式”与 Lua 的“正则表达式”不同的命令/引擎一样,我想更好的说法是:Lua 的“模式”是Lua 特定的“正则表达式”语法/引擎(换句话说,没有两个:)
)
干杯!
有可能因为说真话而遭到反对,我会直截了当地说实话(毕竟答案应该是这样):除了能够为单个匹配调用返回多个捕获(可能在正则表达式中,但以一种更复杂的方式)和%bxy
匹配一对平衡的分隔符(例如各种括号等)并被认为是有用、强大和“更好”的模式,几乎所有 Lua 模式可以做的事情,正则表达式可以做好吧。
另一方面,与正则表达式相比,Lua 模式在“特性”方面的缺点是显着的,并且太多提及(例如,缺少 OR、缺少非捕获组、环视表达式等)。现在,如果 Lua 模式比通常较慢的正则表达式要快得多,那么这将是平衡的,但我不确定是否存在 - 以及在哪里 - 这种比较存在,由于它的轻巧的性质,桌子的使用等等。
Lua 不费心在其工具箱中添加正则表达式的真正原因不能是所需代码的长度(这是胡说八道,现代计算机在 4000 行代码与“仅”500 行代码时甚至不会眨眼,即使它在库中的翻译略有不同),但可能是由于作为脚本语言的事实,假定“父”语言已经包括使用正则表达式的能力。从整体上看,Lua 作为一门语言的设计非常简单、速度快,并且只考虑了必要的特性。它在大多数情况下运行良好,但是如果您需要在这方面的更多功能并且您无法使用 Lua 的其他功能复制它们,那么正则表达式会更全面。
好消息是 Lua 模式和正则表达式之间的语法差异大多很小,所以如果你知道一个,你可以相对容易地适应另一个。