Lua模式匹配与正则表达式
我目前在学习lua。关于lua中的模式匹配,我在lua.org的lua文档中找到了以下句子:
然而,在Lua中进行模式匹配是一种强大的工具,并包括一些难以与标准POSIX实现匹配的功能。
由于我熟悉posix正则表达式,我想知道是否有任何常见示例,其中lua模式匹配与正则表达式相比更好 - 或者我是否误解了该句子?如果有任何常见示例:为什么模式匹配与正则表达式中的任何一种更适合?
原文链接 https://stackoverflow.com/questions/2693334
有没有一些普遍的例子,Lua模式匹配比正则表达式更好用呢?
不是特定的例子,而是Lua模式具有比POSIX正则表达式更高的信噪比。通常更喜欢整体设计而不是特定的例子。
下面是一些有助于设计的因素:
匹配常见字符类型(包括大写字母(
%u
),十进制数字(%d
),空格字符(%s
)等)的语法非常简单。任何字符类型都可以使用相应的大写字母来补充,因此模式%S
匹配任何非空格字符。引用非常简单而规律。 引用字符是
%
,因此它与字符串引用字符\
始终不同,这使得Lua模式比POSIX正则表达式(在需要引用时)更易于阅读。 安全引用符号,无需引用字母,因此您只需按照这个经验法则即可,而无需记忆哪些符号是特殊元字符。Lua提供“捕获”并且可以将多个捕获作为“match”调用的结果返回。 这种接口要比通过副作用捕获子字符串或具有必须被询问以查找捕获的一些隐藏状态要好得多。 捕获语法很简单:只需使用括号。
Lua具有“最短匹配”
-
修改器与“最长匹配”*
运算符相配合。 例如s:find'%s(%S-)%.'
找到由空格前缀和句点后缀的最短的非空格字符序列。Lua模式的表现力与POSIX“基本”正则表达式相当,没有备选操作符
|
。 您要放弃的是具有|
的“扩展”正则表达式。 如果您需要的表现力如此之大,我建议您直接使用[LPEG](http://www.inf.puc-rio.br/~roberto/lpeg/),它在相当合理的成本下提供了上下文无关语法的适当表现力。
在这个讨论中,我想提供一个小小的提示; 我被这个页面搞得特别困惑:
因为它说\s
可以匹配空格,我从其他正则表达式语法中也知道... 所以我在shell中试着用它:
$ lua
Lua 5.1.4 版权所有 (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的查找/替换中的正则表达式,而不是Lua的正则表达式语法(Scite也使用它)。
然后我重新阅读lua-users维基:模式教程,并开始注意到转义字符在@NormanRamsey's答案中不是\
而是%
。所以,尝试这个:
> print("_".. c:match("[%s]*") .."_")
_ _
...确实行得通。
因此,正如我最初认为的那样,Lua的“模式”与Lua的“正则表达式”语法/引擎是不同的命令/引擎,我猜更好的说法是:Lua的“模式”是 Lua特定的“正则表达式”语法/引擎(换句话说,它们不是两个不同的 :)
)。
干杯!
有可能因为说实话会被踩,但我会坦率地说明一点(毕竟作为回答应该如此):除了能够为单个匹配调用返回多个捕获(在正则表达式中也可以,但方式更加复杂)和%bxy
模式可以匹配一对平衡的定界符(例如各种括号等),并且被认为是有用的、强大的和“更好的”,Lua模式几乎可以被认为是所有正则表达式可以做到的事情都能做到的。
然而,当涉及“功能”时,与正则表达式相比,Lua模式的缺点是显著的,不胜枚举(例如,缺乏OR,不支持非捕获组,前瞻表达式等)。如果说Lua模式在一些情况下比通常较慢的正则表达式要快很多,那么这会是平衡的,但我不确定 - 也不知道 - 是否存在这样的比较,一种可以排除通常因其轻量级本质、使用表等带来的常规Lua速度的比较。
Lua没有将正则表达式添加到其工具箱的真正原因可能不是需要编写的代码的长度(那是胡说八道的,现代计算机对于4000行代码与“仅”500行代码没有什么区别,即使在库中的翻译略有不同),而可能是因为作为脚本语言,人们认为“父”语言已经包括了使用正则表达式的能力。明眼人一看总体情况就可以明显看出,Lua作为一种语言,是设计以简单、速度和仅包含必要功能为目标。在大多数情况下它表现得很好,但如果您需要在这个领域具有更多的功能,并且不能使用Lua的其他功能来复制它们,那么正则表达式就更全面了。
好消息是,Lua模式和正则表达式之间的语法差异大多是次要的,因此如果您知道其中一种,则可以相对容易地适应另一种。
- 如何在roblox studio中1:1导入真实世界的地形?
- 求解,lua_resume的第二次调用继续执行协程问题。
- 【上海普陀区】内向猫网络招募【Skynet游戏框架Lua后端程序员】
- SF爱好求教:如何用lua实现游戏内调用数据库函数实现账号密码注册?
- Lua实现网站后台开发
- LUA错误显式返回,社区常见的规约是怎么样的
- lua5.3下载库失败
- 请问如何实现文本框内容和某个网页搜索框内容连接,并把网页输出来的结果反馈到另外一个文本框上
- lua lanes多线程使用
- 一个kv数据库
- openresty 有没有比较轻量的 docker 镜像
- 想问一下,有大佬用过luacurl吗
- 在Lua执行过程中使用Load函数出现问题
- 为什么 neovim 里没有显示一些特殊字符?
- Lua比较两个表的值(不考虑键的顺序)
- 有个lua简单的项目,外包,有意者加微信 liuheng600456详谈,最好在成都
- 如何在 Visual Studio 2022 中运行 Lua 代码?
- addEventListener 返回 nil Lua
- Lua中获取用户配置主目录的跨平台方法
- 如何编写 Lua 模式将字符串(嵌套数组)转换为真正的数组?
http://lua-users.org/wiki/LibrariesAndBindings 包含一个功能列表,其中包括正则表达式库,如果您希望继续使用它们。
回答这个问题(请注意,我决不是 Lua 大师),这种语言在嵌入式应用中有着强烈的传统,其中完整的正则表达式引擎会使在平台上使用的代码大小过大,有时甚至大于 Lua 库本身的大小。
[编辑] 我刚刚在 Programming in Lua 的在线版本(学习该语言的绝佳资源)中发现,这被描述为该语言的原则之一:请参见下面的评论。 [/编辑]
我个人发现,Lua 提供的默认模式匹配可以满足我大部分的正则表达式需求。您的情况可能会有所不同。