(^?)*在这个正则表达式中意味着什么?

dor*_*emi 19 regex lua

我有这个正则表达式:

^(^?)*\?(.*)$
Run Code Online (Sandbox Code Playgroud)

如果我理解正确,这就是它的功能细分:

  • ^ - 从字符串的开头开始匹配
  • (^?)* - 我不知道,但它存储在1美元
  • \? - 匹配问号
  • (.*)$ - 匹配任何内容直到字符串结尾

那么(^?)*是什么意思?

Jar*_*Par 21

(^?)简单地寻找文字字符^.^正则表达式中的字符在用作模式的第一个字符或分组匹配中的第一个字符时仅具有特殊含义[].当在这两个位置之外使用时,^字面意义上解释为在^输入字符串中查找字符

注意:^在第一个和分组位置之外是否按字面解释是特定于正则表达式引擎.我对LUA不够熟悉,不知道它做了什么

  • 没有评论`(^?)*`的无趣性?即它是一个0或一个字符匹配,只匹配字符`^`,匹配0到很多次 - 相同(可能)与`(^*)`相同,除非使用多个组 (3认同)

RBe*_*eig 7

Lua没有传统的正则表达式语言,它有Lua模式.虽然它们看起来很像regexp,但Lua模式是他们自己的一种独特语言,它具有更简单的规则集,最重要的是缺乏分组和交替功能.

解释为Lua模式,该示例将令长期regexp用户感到惊讶,因为许多细节都不同.

PiL描述 Lua模式,并且乍一看与传统的regexp类似,导致混淆.最大的区别可能是缺乏交替操作的,括号仅仅用于标记捕获,量词(,,和)只适用于字符或阶级,是转义字符不是.这个例子可能不是用Lua编写的一个很大的线索是缺少Lua模式引用字符应用于模式字符串中的任何(或理想情况下全部)非字母数字字符,以及可疑使用哪种气味像传统的正则表达式匹配单个文字.|?-+*%\%\??

问题的简单答案是:(^?)*不是推荐的形式,并且匹配^**捕获插入符的存在或不存在.如果这是预期的效果,那么我会写它(%^?)%*以使更清楚.

为了解这种情况,让我们采用给定的模式并将其分析为Lua模式.整个模式是:

^(^?)*\?(.*)$
Run Code Online (Sandbox Code Playgroud)

递交给string.match()它,它将被解释如下:

^ 将匹配锚定到字符串的开头.

( 标志着第一次捕获的开始.

^不在模式的开头或字符类,因此它匹配文字^字符.为清楚起见,应该写成%^.

? 恰好匹配前一个字符的零个或一个.

) 标志着第一次捕获的结束.

*是不是可以量化的东西,所以它匹配文字*字符.为清楚起见,应该写成%*.

\在模式中匹配自身,它不是模式语言中的转义字符.但是,它 Lua短字符串文字中的转义字符,使得后面的字符对于字符串文字解析器不是特殊的,在这种情况下是没有实际意义的,因为?在任何情况下,它都不是特殊的.因此,如果模式用双引号或单引号括起来,那么\它将被字符串解析所吸收.如果用长字符串写(因为[[^(^?)*\?(.*)$]]反斜杠在字符串解析器中存活,就会出现在模式中).

? 恰好匹配前一个字符的零个或一个.

( 标志着第二次捕获的开始.

.匹配任何字符,实际上是类的同义词[\000-\255](记住,在Lua数字转义中是十进制而不是像C中那样的八进制).

* 贪婪地匹配前一个字符的零个或多个.

) 标志着第二次捕获的结束.

$ 将模式锚定到字符串的末尾.

因此,它匹配并捕获^字符串开头*的可选项,然后是一个\未被捕获的可选项,并捕获字符串的其余部分.string.match将成功返回两个字符串(其中一个或两个可能是零长度),或nil失败.

编辑:我修正了一些拼写错误,纠正了我的答案中的错误,Egor在评论中注意到了这一点.我忘了在模式中,特殊符号在不能应用的地方失去了它们的特殊性.这使得第一个星号匹配文字星号而不是错误.大部分答案都落后于级联.

请注意,如果您真的想在Lua中使用真正的正则表达式,那么可以使用提供它的库.也就是说,内置的模式语言非常强大.如果还不够,那么你可能最好采用一个完整的解析器,并使用LPeg,它可以完成正则表达式的所有功能.它甚至带有一个模块,该模块提供完整的正则表达式语法,该语法被转换为LPeg语法以供执行.